VSTO 2013加载项中的拖放图像透明度

本文关键字:拖放 图像 透明度 2013 加载项 VSTO | 更新日期: 2023-09-27 17:57:34

我的PowerPoint加载项中有一个WPF控件,它承载了一个我希望能够拖动的图像&放到活动幻灯片上。我可以将图像显示在幻灯片上,但透明区域呈现为黑色。

我的代码初始化从我的附加行为拖动:

var targetBitmap = new RenderTargetBitmap(
    (int) MyWpfControl.ActualWidth,
    (int) MyWpfControl.ActualHeight,
    96d, 96d, PixelFormats.Default);
targetBitmap.Render(MyWpfControl);
var dataObject = new DataObject(
    DataFormats.Bitmap, 
    targetBitmap);
DragDrop.DoDragDrop(MyWpfControl, dataObject, DragDropEffects.Copy)

我想也许我需要传递一个System.Drawing.Image,于是尝试了这个修改,结果只导致透明区域呈现为灰色:

var targetBitmap = new RenderTargetBitmap(
    (int) MyWpfControl.ActualWidth,
    (int) MyWpfControl.ActualHeight,
    96d, 96d, PixelFormats.Default);
targetBitmap.Render(MyWpfControl);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(targetBitmap));
var ms = new MemoryStream();
encoder.Save(ms);
var dataObject = new DataObject(DataFormats.Bitmap, Image.FromStream(ms, true))
DragDrop.DoDragDrop(MyWpfControl, dataObject, DragDropEffects.Copy)

我做了一个测试,用文件流替换了内存流,并且所写的图像确实具有正确的透明度。

那么我在这里错过了什么?如何保持透明度?

VSTO 2013加载项中的拖放图像透明度

我按照这篇博客文章中的说明解决了这个问题。解决方案是在我的DataObject中使用EnhancedMetafile DataFormat。

编辑:

这是启动拖动操作的代码。

private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Bitmap bitmap = ImageToBitmap(e.Source as System.Windows.Controls.Image);
    DataObject data = new DataObject(DataFormats.EnhancedMetafile, MakeMetafileStream(bitmap));
    DragDrop.DoDragDrop((DependencyObject)e.Source, data, DragDropEffects.Copy);
}

这利用了一个实用程序功能将图像转换为位图:

private Bitmap ImageToBitmap(System.Windows.Controls.Image image)
{
    RenderTargetBitmap rtBmp = new RenderTargetBitmap((int)image.ActualWidth, (int)image.ActualHeight,
        96.0, 96.0, PixelFormats.Pbgra32);
    image.Measure(new System.Windows.Size((int)image.ActualWidth, (int)image.ActualHeight));
    image.Arrange(new Rect(new System.Windows.Size((int)image.ActualWidth, (int)image.ActualHeight)));
    rtBmp.Render(image);
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    MemoryStream stream = new MemoryStream();
    encoder.Frames.Add(BitmapFrame.Create(rtBmp));
    // Save to memory stream and create Bitamp from stream
    encoder.Save(stream);
    return new System.Drawing.Bitmap(stream);
}

这还需要一个实用函数,将位图转换为包含元文件的流,该流取自Stack Overflow。

//从使用.NET将图像转换为WMF?

private MemoryStream MakeMetafileStream(Bitmap image)
{
    Graphics graphics = null;
    Metafile metafile = null;
    var stream = new MemoryStream();
    try
    {
        using (graphics = Graphics.FromImage(image))
        {
            var hdc = graphics.GetHdc();
            metafile = new Metafile(stream, hdc);
            graphics.ReleaseHdc(hdc);
        }
        using (graphics = Graphics.FromImage(metafile))
        { graphics.DrawImage(image, 0, 0); }
    }
    finally
    {
        if (graphics != null)
        { graphics.Dispose(); }
        if (metafile != null)
        { metafile.Dispose(); }
    }
    return stream;
}