【问题标题】:WPF/GDI interop: how do I get correct alpha?WPF/GDI 互操作:如何获得正确的 alpha?
【发布时间】:2012-01-30 22:49:12
【问题描述】:

我创建了一个半透明的测试图像,用 128-alpha 黑色填充。我在两种方法之间交替绘制它:WPF 本机和 GDI 互操作。它们完全不同。 WPF 已正确完成,但 GDI 在绘制之前似乎首先与白色混合:

如果在照片上绘制,GDI 部分使它下面的东西变亮,即使 0,0,0,128 的颜色应该使它下面的东西变暗:

代码如下:

if (iteration % 2 == 0)
    context.DrawImage(new BitmapImage(new System.Uri("I:/test.png")),
                      new Rect(0, 0, 80, 24));
else
{
    var bmp = (D.Bitmap) D.Bitmap.FromFile("I:/test.png");
    var handle = bmp.GetHbitmap();
    var bmpSource = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero,
                    Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
    context.DrawImage(bmpSource, new Rect(0, 0, 80, 24));
    WinAPI.DeleteObject(handle);
    GC.KeepAlive(bmp);
}

对于第二张图片,我更改了 WPF 的 Rect 大小以显示它们不重叠。

如何正确绘制半透明的 GDI 图像?

(是的,由于复杂的原因,它确实必须是 GDI 图像 - 实际上它不是来自文件,而是来自一些外部代码,但问题很容易通过文件重现)

【问题讨论】:

    标签: wpf interop


    【解决方案1】:

    我现在决定避免这个调用,而只是复制原始位图数据。代码:

    var writable = new WriteableBitmap(bmp.Width, bmp.Height,
                          bmp.HorizontalResolution, bmp.VerticalResolution,
                          PixelFormats.Bgra32, null);
    
    var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                          ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    
    writable.WritePixels(new Int32Rect(0, 0, bmp.Width, bmp.Height),
                          data.Scan0, data.Stride * bmp.Height, data.Stride);
    
    GC.KeepAlive(bmp);
    context.DrawImage(writable, new Rect(0, 0, 80, 24));
    

    (这可能需要using 或两个)

    此外,如果可写位图直接用作Image 之类的源,则调用Freeze 有助于防止更新时闪烁,尽管我不明白为什么需要这样做。

    【讨论】:

      【解决方案2】:

      如何正确绘制半透明的 GDI 图像?

      像这样:

      Bitmap targetBitmap = ...
      Bitmap bitmap = new Bitmap(filename);
      using (var g = Graphics.FromImage(targetBitmap))
          g.DrawImage(...);
      

      换句话说,不要为 GDI 到 WPF 的互操作而烦恼(它显然不起作用)。将中间位图保存到文件中,在需要 WPF 时使用 WPF-only,在需要 GDI 时仅使用 GDI。

      【讨论】:

      • 好吧,至少你不是建议我使用 JPEG 作为我的中间格式...信不信由你,但有一堆搜索结果正好表明了这一点!...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2018-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-10-15
      相关资源
      最近更新 更多