[转帖]保存Graphics对象到Bitmap对象

GDI+图片操作全解析:从Bitmap锁定到Graphics绘制的正确姿势 本文深入解析GDI+在WinForm开发中的图像处理技术,重点介绍Bitmap锁定机制与Graphics绘制的高效协作方法。通过内存流处理、资源管理优化和实战案例,帮助开发者避免常见错误,提升图像处理性能与稳定性。 阅读详情

最近在尝试为软件增加截取屏幕的功能,为此学习了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进行图块复制。

c#Bitmap类和Graphics类 C#中的Bitmap类和Graphics类比较输出,对比相同和不同点 立即下载

相关推荐

STM32L431电池供电项目实战:用STOP2模式把功耗降到5uA以下(CubeMX配置详解)

本文详细介绍了如何在STM32L431电池供电项目中利用STOP2模式实现5μA以下的超低功耗设计。通过CubeMX配置、硬件优化和软件策略,成功将农业温湿度监测节点的待机功耗控制在4.7μA,确保CR2032电池供电下3年以上的工作寿命。文章包含完整的低功耗实现路径和实测数据,特别适合物联网边缘设备开发者参考。

weixin_30345577的博客 393

解决Graphics2D drawImage图片失真的问题

常规的写法 graphics.drawImage(originalBufferedImage, rectangle.x, rectangle.y, rectangle.width, rectangle.height, null); 优化的写法 graphics.drawImage(

慧心斋 2万+

STM32 伺服电机 指令脉冲+方向位置控制模式 主从定时器 实现PWM脉冲数精确控制

实验室有个项目涉及到多个步进电机以及伺服电机的控制,需要电机得到一个触发信号后精确移动一段距离。 下面以单个伺服电机控制为例,利用伺服电机的指令脉冲加方向位置控制模式实现jing'que ...

phcdd的博客 2万+

C# 关于画图Graphics Bitmap image

关于GDI+ 的使用,就对点,线,面的画的操作,图像剪裁,缩放等等操作,了解各种常用的方法和属性。常用命名空间:System.Drawing;System.Drawing.Image;System.Drawing.Drawing2D;Graphics类封装了一个GDI+绘图图面,提供将对象绘制到显示到设备的方法。Graphics叫画板,只不过这个画板中带了很多工具。但画图时你要定义画板的大小,颜色等

Steven Lei的博客 1万+

当GO.db安装失败时,生物信息学新手应该知道的5个底层逻辑

本文为生物信息学新手提供了解决GO.db安装失败的5个关键底层逻辑,包括网络连接与镜像源设置、版本兼容性检查、依赖关系管理、SQLite存储机制理解以及调试技巧。特别针对Bioconductor的GO.db包安装问题,详细介绍了如何通过切换国内镜像、管理版本冲突和解决依赖问题来成功安装,帮助用户高效克服常见安装障碍。

weixin_29062823的博客 407

深度学习模型轻量化方法之【量化】

量化虽然有着硬件友好和功效提升的特点,但它也引入了模型性能的折衷。因此,设计有效的量化策略需要在模型大小、性能以及运算速度之间做出平衡。随着深度学习算法和硬件加速技术的快速发展,量化方法在使深度网络轻量化和提高部署效率方面持续发挥着重要作用。

m0_73916791的博客 2846

图形图像处理 - 我们所不知道的 Bitmap

Bitmap 是怎么开辟内存的?内存是怎么复用和销毁的?本地资源图片应该怎么去做适配? 打开我们自己的 APP 发现占用内存较大的一般都是本地资源图片,我们该如何去优化这些内存? 大家以后如果有涉及直播这一块的业务,直播间会有各种活动和各种复杂动画,线上 buggly 肯定会有大量的 OOM ,我们怎样才能在 OOM 前去 dump 线上内存来做优化分析? Bitmap 我们是再熟悉不过了,首...

z240336124的专栏 955

手把手教你为FPGA项目集成HyperRAM IP核:从AXI接口封装到上板调试全流程

本文详细介绍了如何为FPGA项目集成HyperRAM IP核,涵盖从AXI接口封装到上板调试的全流程。通过对比DDR3L、PSRAM和HyperRAM的性能指标,突出HyperRAM在低功耗和小封装尺寸方面的优势,并提供硬件连接、AXI4-Lite接口设计、状态机优化及调试技巧等实用内容,帮助开发者高效完成FPGA项目中的内存扩展。

weixin_32103009的博客 283

保存Graphics对象到Bitmap对象

    最近在尝试为软件增加截取屏幕的功能,为此学习了System.Drawing命名空间的Graphics、Image、Bitmap等GDI+类,这些类都很方便使用。但是它们大多都是对原有GDI API的封装,也增加了一些新的东西;不过封装得并不彻底,有些功能还是需要调用GDI API才能实现。我武断的认为Image、Bitmap、Metafile跟HBITMAP对应,Graphics跟HDC对...

weixin_33744141的博客 592

Nginx的启动、停止与重启命令(非yum方式安装)图解版

目录一、Nginx启动二、Nginx停止的三种方式2.1、第一种方式(从容停止)2.2、第二种方式(快速停止)2.3、第三种方式(强制停止)三、Nginx重启3.1、首先,验证nginx配置文件是否正确3.1.1、验证nginx配置文件(方法一)3.1.1、验证nginx配置文件(方法二)3.2、最后,重启Nginx服务3.2.1、重启Nginx服务(方法一)3.2.2、重启Nginx服务(方法二) 一、Nginx启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 /usr/loc

小志的博客 6851

【ARM Coresight | AMBA BUS | Cache 与 MMU/MPU | CoreLink | GCC | CSH 专栏导读】

1. ARM Coresight(SoC-400/SoC-600) 专栏 2. ARMv8/v9 CPU/Cache 专栏 3. Linux ARM AMBA 总线 专栏 4. Trace32/DS-5 专栏。。。

CodingCos的博客 8241

java graphics gdi_如何将GDI Graphics / HDC保存到文件中?

我无法将从设备上下文HDC派生的GDI Graphics对象保存到文件中 .What works :我能够保存从Bitmap派生的GDI图形 . 示例代码(Win32):Color color(255, 0, 0);Pen pen(color, 2.0f);CLSID pngClsid;if(GetEncoderClsid(L"image/bmp", &pngClsid) < 0) ...

weixin_32049085的博客 274

innovus:addRepeaterByRule用法

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?addRepeaterByRule不管transition/timing violation,只根据约束的length/cap/fanout等等去给net 插buffer。

m0_61544122的博客 1089

Android开发中一种原封不动地保存Bitmap数据的办法

最近一款软件需要保存图像时,不能有一丝一毫的失真,而且只限于本APP中打开。因此Bitmap.compress这种API是肯定不能用了。而网上的Android开发资料在保存Bitmap的时候都是用这个API的,千篇一律,没啥好借鉴的。所以我直接凭我的认知,写了几句代码实现了这个功能。 首先已知,安卓的Bitmap类提供了copyPixelsFromBuffer和copy...

轮子初级玩家 4691

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Bitmap使用PictureBox后提示Bitmap占用

问题:Bitmap被占用 原因:如果直接把图片bitmap放在了PictureBox里,会出现图像一直被占用,这时候再去对bitmap进行一些操作,就不行了,比如获取图像的width和height 解决: public void ShowImage(Bitmap bitmap) { Bitmap bmp = new Bitmap(bitmap.Width, bitmap.Heigh...

马儿不吃草 1178

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

保存自己在Graphics上绘制的图形

sunnyzls的专栏 7495

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

无法从带有索引像素格式的图像创建 Graphics 对象

在使用Graphics.FromImage方法的时候,如果传入的System.Drawing.Image图像是索引像素格式,那么将会引发异常并提示以下消息:“无法从带有索引像素格式的图像创建 Graphics 对象。”。 先说下本人遇到的具体情况:由于网站需要添加一个上传图片自动打水印的功能,所以需要使用System.Drawing.Graphics类对图像重新绘制,将水印图片绘制到图片上。但在实...

极客神殿 4379

android tif bitmap,c#数字图像处理(一)Bitmap类、 Bitmapdata类和 Graphics类

Bitmap类、 Bitmapdata类和 Graphics类是C#图像处理中最重要的3个类,如果要用C#进行图像处理,就一定要掌握它们。1.1 Bitmap类Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成。因此 Bitmap是用于处理由像素数据定义的图像的对象。Bitmap类类的主要方法和属性如下:Get Pixel方法和 Setpiⅸel方法:获取和设置一个...

weixin_32090653的博客 312

android bitmap 保存到本地_Android全屏截图的方法,返回Bitmap并且保存在SD卡上

今天做分享,需求是截图分享,做了也是一个运动类的产品,那好,我们就直接开始做,考虑了一下,因为是全屏的分享,所有很自然而然的想到了View的getDrawingCache()方法来获取Bitmap,看到网上有人说截取不了WebView上的图片,倒是没有去尝试,因为我们的应用不需要,不过有时间还是要去试试,占占坑,这篇博客只是记录一下知识点,没什么技术含量我们写个小Sample就好了activity...

weixin_39601641的博客 321

位图上下文 bitmap graphics context

这次我们要来学习如何为一张图片添加水印,为图片添加水印是现在很多社交软件都有实现的一个功能,我们在微博上面查看好友的图片的时候,图片的右下方经常附带有发表该微博的作者的名字,这就是我们今天要实现的效果。

乐事派的专栏 1185

用graphics画一个矩形 怎么能保存到一张图片上!

<br />HRESULT SaveImage( BYTE * pBuffer, BITMAPINFOHEADER *bmpInfo) { Gdiplus::BitmapData bitmapData; bitmapData.Width = bmpInfo->biWidth; bitmapData.Height = bmpInfo->biHeight; bitmapData.Stride = 3 * bmpInfo->biWidth; bitmapData.PixelFormat = Pixel

长豆角 2677

android.graphics.bitmap jar,将Android.Graphics.Bitmap转换为Image

我试图获取视图的屏幕截图如下.我正在获取Bitmap,我需要将其转换为Image以添加到PDF生成器中.using (var screenshot = Bitmap.CreateBitmap(200,100,Bitmap.Config.Argb8888)){var canvas = new Canvas(screenshot);rootView.Draw(canvas);using (var sc...

weixin_35082950的博客 450
上一篇: Erlang -- (Windows平台)文件夹说明
CSharp2009
博客等级 码龄19年 0粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值