从WPF System.Windows.Shapes.Path创建映像

时间:2014-05-10 14:27:18

标签: c# wpf xaml bitmap transparency

我有一条路。它在ContentControl

中正确显示
<ContentControl
    Name="PathContainer"
    Content="{Binding Path}"
    RenderTransform="{StaticResource ScaleTransform}"
    Width="Auto"
    Height="Auto"
    Background="Transparent"
    />

但我想把它复制到剪贴板。以下内容创建了一个正确大小的纯黑色位图。如果我将画笔更改为白色,则会创建一个正确大小的纯白色位图。如果我不是创建此Canvas,而是从在UI中托管ContentControl的实际Path进行渲染,我会使用Path获得正确大小的位图在它上面绘制,但看起来是一个不透明的黑色背景(除非我将背景改为PapayaWhip或其他东西,这符合你所期望的)。

当我说'#34;似乎是一个不透明的黑色背景&#34;时,我的意思是当我用System.Windows.Clipboard.CopyImage()将其复制到剪贴板并将其粘贴到VS图标或位图编辑器时,背景粘贴的图像是黑色而不是透明的,并且应该是半透明的消除锯齿的像素是它们看起来在黑色背景上的颜色。

所以,有两个问题:

首先:以下代码是否已损坏,或者我只是想尝试做一些你无法做到的事情?它不会在WPF中抛出任何异常,FWIW。

第二:如何在WPF中使用alpha通道制作位图?我是否应该放弃在所有这些节省劳动力的抽象上浪费我的时间,敲打BITMAPINFOHEADER,并手动创建ARGB四边形?

public BitmapSource CreateImage(Transform tfm)
{
    var path = CreatePath();

    var rcBounds = path.Data.GetRenderBounds(GetPen());

    if (null != tfm)
    {
        rcBounds = tfm.TransformBounds(rcBounds);
    }

    int pxWidth = (int)Math.Round(rcBounds.Width);
    int pxHeight = (int)Math.Round(rcBounds.Height);

    var canvas = new System.Windows.Controls.Canvas();

    canvas.Width = pxWidth;
    canvas.Height = pxHeight;
    canvas.Margin = new System.Windows.Thickness(0);
    canvas.Background = Brushes.Transparent;

    canvas.Measure(new Size(canvas.Width, canvas.Height));
    canvas.Arrange(new Rect(new Size(canvas.Width, canvas.Height)));
    canvas.UpdateLayout();

    canvas.Children.Add(path);

    canvas.RenderTransform = tfm;

    RenderTargetBitmap rtb = new RenderTargetBitmap(pxWidth, pxHeight, 
                                     96, 96, PixelFormats.Pbgra32);

    rtb.Render(canvas);

    return BitmapFrame.Create(rtb);
}

1 个答案:

答案 0 :(得分:3)

似乎没有必要使用Canvas。您可以直接将Path渲染到RenderTargetBitmap中,例如以下带透明背景的蓝色圆圈:

var path = new Path
{
    Data = new EllipseGeometry(new Point(100, 100), 100, 100),
    Fill = Brushes.Blue
};

var bounds = path.Data.GetRenderBounds(null);
path.Measure(bounds.Size);
path.Arrange(bounds);

var bitmap = new RenderTargetBitmap(
    (int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(path);