保存Graphics对象到Bitmap对象
最近在尝试为软件增加截取屏幕的功能,为此学习了System.Drawing命名空间的Graphics、Image、Bitmap等GDI+类,这些类都很方便使用。但是它们大多都是对原有GDI API的封装,也增加了一些新的东西;不过封装得并不彻底,有些功能还是需要调用GDI API才能实现。我武断的认为Image、Bitmap、Metafile跟HBITMAP对应,Graphics跟HDC对应。
在GDI+中,我们可以很方便的用Graphics.FromImage方法来操作Image中的内容,并将其保存回图片文件。那么,我们怎么才能保存Graphics到图片文件呢?创建一个Bitmap对象,复制Graphics g1的内容到Bitmap的Graphics g2,然后保存Bitmap对象到文件。复制过程我们必须通过PINVOKE调用BitBlt函数来实现。下面是该函数的声明:
[DllImport("gdi32.dll", CharSet=CharSet.Auto, SetLastError=true, ExactSpelling=true)]
public static extern int BitBlt(HandleRef hDC, int x, int y, int nWidth, int nHeight, HandleRef hSrcDC, int xSrc, int ySrc, int dwRop);
参数中的各种DC可以用Graphics.GetHdc得到;最后一个参数光栅操作码很多,截取屏幕用的SRCCOPY值是0xcc0020,完整的光栅操作码可以查看MSDN的“Ternary Raster Operations”部分。
示例代码如下:
//这里假设要保存一个窗体的内容
int width=800; //获取宽度
int height=600; //获取高度
const int SRCCOPY=0xcc0020; //复制图块的光栅操作码
Bitmap bmSave=new Bitmap(width,height); //用于保存图片的位图对象
Graphics gSave=Graphics.FromImage(bmSave); //创建该位图的Graphics对象
HandleRef hDcSave=new HandleRef(null,gSave.GetHdc()); //得到句柄
Graphics gSrc=formMain.CreateGraphics(); //创建窗体的Graphics对象
HandleRef hDcSrc=new HandleRef(null,gSrc.GetHdc());
BitBlt(hDcSave,0,0,width,height,hDcSrc,0,0,SRCCOPY);
gSrc.ReleaseHdc();
gSave.ReleaseHdc();
bmSave.Save(@"C:\test.bmp");
gSrc.Dispose();
gSave.Dispose();
bmSave.Dispose();
关于Graphics.CopyFromScreen方法
该方法在内部其实也使用BitBlt来进行图块复制,但是它只是固定的复制屏幕的内容,我们不能指定复制的源。
如果您需要截取屏幕的内容,可以使用以下代码:
int screenWidth=System.Windows.Forms.SystemInformation.VirtualScreen.Width; //屏幕宽度
int screenHeight=System.Windows.Forms.SystemInformation.VirtualScreen.Height; //屏幕高度
Bitmap bmSave=new Bitmap(screenWidth,screenHeight);
Graphics g=Graphics.FromImage(bmSave);
g.CopyFromScreen(0,0,0,0,new Size(screenWidth,screenHeight),CopyPixelOperation.SourceCopy);
bmSave.Save(@"C:\test.bmp");
g.Dispose();
bmSave.Dispose();
如果需要复制顶层窗体的可见部分,也可以使用Graphics.CopyFromScreen,但是需要用PointToScreen方法先得到屏幕坐标。
如果需要复制任意的窗体或者控件,先用Control.Handle得到控件句柄,然后再用GetDC()函数得到HDC,再用BitBlt进行图块复制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)