[转帖]保存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进行图块复制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值