我正在使用此代码来捕获屏幕:
public Bitmap CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Bitmap img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
然后我想将位图转换为 256 色(8 位)。我尝试了此代码,但收到有关无法从索引位图格式创建图像的错误:
Bitmap img8bit = new Bitmap(img.Width,img.Height,
System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
Graphics g = Graphics.FromImage(img8bit);
g.DrawImage(img,new Point(0,0));
我确实看到了一些在不同格式之间转换位图的示例,但就我而言,我正在寻找从屏幕捕获时执行此操作的最佳方法。例如,如果有一种方法可以通过创建一个 8 位位图来更好地工作,然后将屏幕blit 到那个位置,那将比先将屏幕捕获到可兼容位图然后转换它更可取。除非最好捕获然后转换。
我有一个使用 Borland Builder 6.0 VCL 用 C++ 编写的程序,我正在尝试模仿它。在这种情况下,只需为 VCL 的 TBitmap 对象设置像素格式即可。我注意到 Bitmap.PixelFormat 在 .NET 中是只读的,呃。
更新:就我而言,我认为答案不像其他需要找出最佳调色板条目的用法那样复杂,因为使用屏幕 DC 的 Graphics.GetHalftonePalette 应该没问题,因为我的原始位图来自屏幕,而不是只是可能来自文件/电子邮件/下载/等的任何随机位图。我相信有些事情可以用涉及 DIB 和 GetHalftonePalette 的 20 行代码来完成——只是还没有找到。