使用DrawingVisual的WPF .png叠加层

时间:2017-11-16 18:15:35

标签: c# wpf

我正在使用这个例子 - 我在这里找到 - 覆盖两个.png图像,然后将结果保存为第三个.png图像。

输入图像是:

Transparent frame

Opaque background

输出图像应该(在我的梦中):

enter image description here

而我得到了这个:

enter image description here

以下是代码:

    public static void Test()
    {
        // Loads the images to tile (no need to specify PngBitmapDecoder, the correct decoder is automatically selected)
        BitmapFrame frame1 = BitmapDecoder.Create(new Uri(@"D:\_tmp_\MaxMara\Test\Monoscope.png"), BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames.First();
        BitmapFrame frame2 = BitmapDecoder.Create(new Uri(@"D:\_tmp_\MaxMara\Test\OverlayFrame.png"), BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames.First();

        // Gets the size of the images (I assume each image has the same size)
        int imageWidth = 1920;
        int imageHeight = 1080;

        // Draws the images into a DrawingVisual component
        DrawingVisual drawingVisual = new DrawingVisual();
        using (DrawingContext drawingContext = drawingVisual.RenderOpen())
        {
            drawingContext.DrawImage(frame1, new Rect(0, 0, imageWidth, imageHeight));
            drawingContext.DrawImage(frame2, new Rect(0, 0, imageWidth, imageHeight));
        }

        // Converts the Visual (DrawingVisual) into a BitmapSource
        RenderTargetBitmap bmp = new RenderTargetBitmap(imageWidth, imageHeight, 300, 300, PixelFormats.Pbgra32);
        bmp.Render(drawingVisual);

        // Creates a PngBitmapEncoder and adds the BitmapSource to the frames of the encoder
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bmp));

        // Saves the image into a file using the encoder
        using (Stream stream = File.Create(@"D:\_tmp_\MaxMara\Test\Result.png"))
            encoder.Save(stream);
    }

注意:如果我使用100 dpi,如:

RenderTargetBitmap bmp = new RenderTargetBitmap(imageWidth, imageHeight, 100, 100, PixelFormats.Pbgra32);

我得到了正确的结果(意思是:我想要的结果)。

我不明白为什么。所有图像均为300 DPI

有人可以对这个话题有所了解吗? 谢谢你的时间

的Orf

1 个答案:

答案 0 :(得分:1)

请勿使用位图的PixelWidthPixelHeight(即您的imageWidthimageHeight值)将其绘制到DrawingContext中。

请改用他们的WidthHeight值,因为这些值会根据绘图的要求提供device-independent units (1/96th inch per unit)中的位图大小。

using (var drawingContext = drawingVisual.RenderOpen())
{
    drawingContext.DrawImage(frame1, new Rect(0, 0, frame1.Width, frame1.Height));
    drawingContext.DrawImage(frame2, new Rect(0, 0, frame2.Width, frame2.Height));
}