【问题标题】:C# Bitmap object, color appearing as transparentC#位图对象,颜色显示为透明
【发布时间】:2012-03-25 17:24:32
【问题描述】:

我正在使用 C# 编写一个程序,该程序会截取用户屏幕上的药水的屏幕截图。对于大多数人来说,它应该可以正常工作,但我最近遇到了一个问题。似乎(至少)一种像素颜色在输出图像中始终显示为透明。颜色 #0D0B0C (RGB 13, 11, 12) 的任何实例在保存的 png 中都显示为透明。这是将 PixelFormat 设置为 Format32bppArgb。如果我将其设置为 Format32bppRgb 或 Format24bppRgb,则相同的像素颜色在保存的 png 中显示为黑色。

我不知道是什么原因造成的,但我唯一能够“修复”的就是在执行 CopyFromScreen() 之前将图形对象清除为该颜色。我不愿意这样做,但有几个原因。首先,我不知道这是否是唯一有问题的颜色(16,777,216 种颜色有很多可能性),其次,我讨厌 hack 修复,这似乎是 hack 修复。

任何人都可以阐明可能导致此问题的原因吗?我在位图创建时弄乱了 PixelFormat,在 CopyFromScreen 方法中弄乱了 CopyPixelOperation,似乎没有任何效果。将图形对象清除为该颜色“修复”这一事实似乎告诉我透明度来自屏幕数据本身,但这没有意义。我已经盯着这个太久了,我想我需要一个新的视角来看待它。如果有人知道为什么会发生这种情况,我很想听听。谢谢。

【问题讨论】:

    标签: c# image graphics bitmap pixelformat


    【解决方案1】:

    我只需将 CopyFromScreen 请求到一个根本没有 Alpha 通道的位图中,例如:

    Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height,     System.Drawing.Imaging.PixelFormat.Format32bppRgb);
    Graphics graphics = Graphics.FromImage(bitmap as Image);
    graphics.CopyFromScreen(bounds.Location, new Point(0, 0), bitmap.Size);
    

    我确认这有使用 Format32bppArgb 但没有使用 Format32bppRgb 的透明像素孔

    【讨论】:

      【解决方案2】:

      在将控件渲染为位图时遇到了完全相同的问题。设法通过使用 PixelFormat.Format32bppRgb 创建另一个位图并将其 BitBlt'ing 来修复它。希望这会有所帮助!

      public class ScreenCapture
      {
          [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
          private static extern bool BitBlt(
              IntPtr hdcDest, // handle to destination DC
              int nXDest, // x-coord of destination upper-left corner
              int nYDest, // y-coord of destination upper-left corner
              int nWidth, // width of destination rectangle
              int nHeight, // height of destination rectangle
              IntPtr hdcSrc, // handle to source DC
              int nXSrc, // x-coordinate of source upper-left corner
              int nYSrc, // y-coordinate of source upper-left corner
              System.Int32 dwRop // raster operation code
              );
      
      
          /// <summary>
          /// Returns an image of the control
          /// </summary>
          /// <param name="control">The control object whose image is wanted</param>
          /// <returns>Image of the control</returns>
          /// <remarks>This is based on code from 
          /// http://www.dotnet247.com/247reference/a.aspx?u=http://www.c-sharpcorner.com/Code/2002/April/ScreenCaptureUtility.asp 
          /// with changes made to prevent 0D0B0C transparency issues</remarks>
          public static Image GetControlImage(Control control)
          {
              Graphics g1 = control.CreateGraphics();
      
              // Create a bitmap the same size as the control
              Image MyImage = new Bitmap(control.ClientRectangle.Width, control.ClientRectangle.Height, PixelFormat.Format32bppRgb);
              (MyImage as Bitmap).SetResolution(g1.DpiX, g1.DpiY);
      
              Graphics g2 = Graphics.FromImage(MyImage);
      
              IntPtr dc1 = g1.GetHdc();
              IntPtr dc2 = g2.GetHdc();
      
              // BitBlt from one DC to the other
              BitBlt(dc2, 0, 0, control.ClientRectangle.Width, control.ClientRectangle.Height, dc1, 0, 0, 13369376);
      
              // Release Device Contexts
              g1.ReleaseHdc(dc1);
              g2.ReleaseHdc(dc2);
      
              // This statement runs the garbage collector manually
              // (If not present, uses up large amounts of memory...)
              GC.Collect();
      
              return MyImage;
          }
      }
      

      【讨论】:

        【解决方案3】:

        alpha 值可能是 0 吗?你检查了吗?

        因为 Format32bppArgb 和 Format32bppRgb 最大的不同在于第二种格式不知道 alpha 通道。

        【讨论】:

        • 打印屏幕会产生正确的图像,就像我在 OP 中所说的那样,当我将其设置为 Format32bppRgb 时,相同的像素会显示为黑色(当它们应该是 #0D0B0C 时)。其他像素都不是透明的,这听起来像是在打印屏幕中也会出现的东西。
        • 如何截取屏幕截图?
        • 就像我在 OP 中所说的,我使用图形对象和 CopyFromScreen()。
        • new Bitmap(width, height, PixelFormat.Format32bppArgb) 更改为 new Bitmap(width, height, PixelFormat.Format32bppRgb) 为我解决了这个问题。
        猜你喜欢
        • 2020-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-09
        • 2012-12-11
        • 2012-12-17
        • 2017-01-18
        • 2013-01-14
        相关资源
        最近更新 更多