我正在使用C#中的程序处理用户屏幕的一部分屏幕截图。它应该尽可能地工作,但我最近碰到了一个问题。似乎(至少)一个像素颜色在输出图像中始终显示为透明。颜色#0D0B0C(RGB 13,11,12)的任何实例在保存的png中显示为透明。这是将PixelFormat设置为Format32bppArgb。如果我将其设置为Format32bppRgb或Format24bppRgb,则相同的像素颜色在保存的png中显示为黑色。
我不知道是什么原因引起了这种情况,但我唯一能做的就是修复"它是在执行CopyFromScreen()之前将图形对象清除为该颜色。虽然出于几个原因,我不愿意这样做。首先,我不知道这是唯一有问题的颜色(那里有16,777,216种颜色,还有很多种可能性),其次,我讨厌黑客修复,这似乎是一个黑客修复。
任何人都可以解释可能导致此问题的原因吗?我在创建位图时使用了PixelFormat,并且在CopyFromScreen方法中使用了CopyPixelOperation,似乎没有任何效果。将图形对象清除为该颜色"修复"它似乎告诉我,透明度来自屏幕数据本身,但这没有任何意义。我已经盯着这个太久了,我想我需要一个全新的视角。如果有人知道为什么会发生这种情况,我很乐意听到它。谢谢。
答案 0 :(得分:1)
alpha值可能为0吗?你检查过了吗?
因为Format32bppArgb和Format32bppRgb之间的巨大差异是第二种格式不知道alpha通道。
答案 1 :(得分:0)
将控件渲染到位图时会出现完全相同的问题。通过使用PixelFormat.Format32bppRgb和BitBlt来创建另一个位图来管理它来修复它。希望这有帮助!
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;
}
}
答案 2 :(得分:0)
我只需要将CopyFromScreen请求到一个根本没有Alpha通道的位图,例如:
addStep.Add(
new XElement("proceduralStep",
new XAttribute("id", stepNumber + "-" + counter2.ToString("D4")),
new XElement("para", subDataBox.Text)));
我确认它具有Format32bppArgb的透明像素孔,但没有使用Format32bppRgb
答案 3 :(得分:-2)
看起来你的屏幕上有坏像素。