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

本文关键字:Path 创建 图像 Shapes Windows WPF System | 更新日期: 2023-09-27 18:02:52

我有一个路径。它在ContentControl:

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

但是我想把它复制到剪贴板。下面的代码创建了一个尺寸正确的纯黑色位图。如果我将笔刷设置为白色,它会创建一个大小正确的纯白色位图。如果,而不是创建这个Canvas,我从实际的ContentControl中渲染,它在UI中承载Path,我得到一个正确大小的位图,上面画着Path,但看起来是一个不透明的黑色背景(除非我把背景改成PapayaWhip或其他东西,这是你所期望的)。

当我说"似乎是一个不透明的黑色背景"时,我的意思是当我用System.Windows.Clipboard.CopyImage()将其复制到剪贴板并将其粘贴到VS图标或位图编辑器中时,粘贴图像的背景是黑色而不是透明的,并且应该是半透明的抗锯齿像素是黑色背景上的颜色。

那么,两个问题:

第一个:下面的代码是坏的,还是我只是想做一些你不能做的事情?它不会抛出任何异常,在WPF中。

第二:如何在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);
}

从WPF System.Windows.Shapes.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);