MFC-GDI和GDI+
Posted 天子骄龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC-GDI和GDI+相关的知识,希望对你有一定的参考价值。
设备环境DC的概念:
设备环境DC(Device Context又称为设备上下文,也称为设备描述表)。它是一个关于如何绘制图形的方法的集合,它既可以绘制各种图形,也可以确定在应用窗口中绘制图形的方式,就是绘图模式和映射模式。
在Win32编程中,设备环境是用HDC来标识。H的意思Handle句柄的意思。
【DC可以理解为画布】
CPaintDC 、CWindowDC、 CClientDC、 CDC的区别与联系:
DC就是设备上下文(Device Context, DC),可以把它理解成“画布”。
操作系统本来是使用HDC(HDC是DC的句柄,API中的一个类似指针的数据类型.)进行绘画的。
MFC中把HDC包装成了CDC类(MFC类的前缀都是C开头的),提供给程序员使用。
CPaintDC的父类就是CDC,换句话说两者底层使用同一种方法进行绘图。
MFC是通过消息泵信息处理的。CPaintDC内部发出绘图消息给系统。所以描画画面时,最好使用CPaintDC。
CDC只是HDC的包装,不包含绘图消息的发送。所以,创建图片文件(不需要刷新画面)等处理,需要使用CDC
一句话概括:
CPaintDC 无效区dc, 相当于BeginPaint, EndPaint
CClientDC 客户区dc, 相当于GetDC, ReleaseDC
CWindowDC 整窗口dc, 相当于GetWindowDC, ReleaseDC
CDC 任何dc, 相当于CreateDC, DeleteDC
GDI+ 实现透明水印和文字
最近给《JPEG浏览缩放器》增加了水印功能,在设计的过程中,参考了网上的文章,但是发现文章使用的GDI+ API封装包不是我现在使用的那一套,目前DELPHI使用的GDI+ API封装包有两套,一套包括以DirectDraw.*、Gdipapi.*、Gdipobj.*、 Gdiputil.*为文件名,另一套以GdipExport.*、Gdiplus.*、GdipTypes.*、GdipUtil.*为文件名,我使用的是前者,文章所用的是后者,于是将文章原代码根据我用的那套GDI+ API封装包进行修改,修改后的代码如下:
USES GDIPUTIL,GDIPAPI,GDIPOBJ;
procedure Form1.SaveJpg(sname,Dname:string);
//Sname-源JPEG文件名,Dname-加水印后的JPEG文件名
const
ColorMatrix: TColorMatrix =
( //R G B A V
(1.0, 0.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 0.0, 0.3, 0.0),
(0.0, 0.0, 0.0, 0.0, 1.0)
);
var
font1: TGPFont;
bmp,Watermark:TGPBitmap;
g: TGPGraphics;
sb1: TGPSolidBrush;
imageAttr:TGpImageAttributes;
JPG: TGPImage;
strFormat: TGpStringFormat;
EncoderClsid: TGUID;
Parameters: TEncoderParameters;
Quality: Integer;
begin
//载入JPEG图片
jpg:=TGPimage.Create(sname);
//根据JPEG图片的SIZE创建一个BMP
Bmp := TGPBitmap.Create(jpg.GetWidth,jpg.GetHeight, PixelFormat32bppRGB);
//绘制JPEG底图
g := TGPGraphics.Create(BMP);
g.SetInterpolationMode(InterpolationModeHighQualityBicubic);
g.DrawImage(Jpg, MakeRect(0, 0, Jpg.GetWidth,,Jpg.GetHeight), 0, 0, Jpg.GETwidth, Jpg.GETheight, UnitPixel);
//使用IMAGE控件里的BMP格式图片做水印图
Watermark:=TGPBitmap.Create(Image1.Picture.Bitmap.Handle, PixelFormat32bppRGB);
// 设置水印的透明度为0.3(根据ColorMatrix的[3][3]=0.3)
imageAttr := TGpImageAttributes.Create;
imageAttr.SetColorMatrix(ColorMatrix:);
//绘制水印,位置在原图的左上角X=20,Y=20位,强制大小为100*100。
g.DrawImage(Watermark, MakeRec(20,20, 100,100),0, 0
Image1.Picture.Bitmap.Width,Image1.Picture.Bitmap.Height , UnitPixel, imageAttr);
//加入水印文字
font1 := TGpFont.Create(‘黑体‘,20);
sb1 := TGPSolidBrush.Create($50000000); //黑色阴影打底
sb2 := TGPSolidBrush.Create($50FFFFFF); //白色字在上面
strFormat := TGpStringFormat.Create;
strFormat.SetAlignment(StringAlignmentNear);
//分别用黑色和白色错开1个象素绘制文字,产生阴影效果.
g.DrawString(‘冲瞳软件工作室‘,7,font1,MakeRect(151,21,Jpg.GetWidth /1,Jpg.GetHeight),strFormat,sb1);
g.DrawString(‘冲瞳软件工作室‘,7,font1,MakeRect(150,20,Jpg.GetWidth /1,Jpg.GetHeight),strFormat,sb1);
// ------设置图像品质编码参数,保存文件---------------------
Quality :=90;
Parameters.Count := 1;
Parameters.Parameter[0].Guid := EncoderQuality;
Parameters.Parameter[0].Type_:= EncoderParameterValueTypeLong;
Parameters.Parameter[0].NumberOfValues := 1;
// 设置参数的值:品质等级,最高为100,图像文件大小与品质成正比
Parameters.Parameter[0].Value := @Quality;
GetEncoderClsid(‘image/jpeg‘‘, EncoderClsid);
Bmp.Save(dname, EncoderClsid, @Parameters);
//释放
sb1.Free;
font1.Free;
strFormat.Free;
jpg.Free;
bmp.Free;
ImageAttr.Free;
Watermark.Free;
g.Free;
end;
在网上的文章中,TGPSolidBrush.Create($50000000); 这条函数用的参数是$99000000,绘制的文字是不透明的,而在网上也没有搜索到绘制透明文字的代码,一度使我认为要使文字透明,必须先保存成图片,再用绘制水印的方法实现,后来想了一下,是不是ARBG的A(透明度)太大了呢,在GDI+中,使用ARBG,$99000000表示A=$99,试将颜色的A都改成$50,文字透明的效果就出来了。
以上是关于MFC-GDI和GDI+的主要内容,如果未能解决你的问题,请参考以下文章
适用于所有 Win32 程序员的在 Windows Aero Glass(DWM、GDI、GDI+)上绘图的文档和 API 示例