初次接触GDI+,做了一个工具函数库。抛砖引玉,公开源码,请大家看看这个思路对不对,以及实现的方法是不是高效
时间:2011-10-08
来源:互联网
以前做过一个批量缩小照片的工具,因为标准canvas的缩小效果太差,具体的缩小是利用cximage(vc编译的外部程序)实现的
后来做一个照片-标签管理工具(觉得google的picasa的标签太不够用了,它的人脸自动识别倒不错。这个工具支持树形层次的任意多、任意层的标签),也需要把照片缩略显示以便选择、查看
国庆时做拼图工具,也需要把原图缩放成界面大小,同时还需要随意割取区域显示到另一个区域,所以,标准canvas又不够用了
所以终于留意到gdi+了
开始以为程序uses gdiplus后,原来标准的canvas的方法就能自动拥有gdi+的效果了
结果,不是这样的。。。。。
于是转为希望仅仅在需要较好处理效果的地方能利用gdi+,
最需要的地方自然是:
1、能加载任意格式的图形文件(本来只能加载bmp/icon/wmf等格式,users jpeg后能加载jpg了,但是gif/png。。。呢)
2、图像的缩放,标准canvas的效果是很差的,gdi+则包含了效果不错的处理算法
3、图像的旋转、对称翻转(jpeg好像只是文件头有对应的标志,而不用真正重新处理整个图像[未确定])
目前只实现了1、2,抛砖引玉,公开源码,请大家看看这个思路对不对,以及实现的方法是不是高效(有没有迂回、冗余了):
Delphi(Pascal) code
后来做一个照片-标签管理工具(觉得google的picasa的标签太不够用了,它的人脸自动识别倒不错。这个工具支持树形层次的任意多、任意层的标签),也需要把照片缩略显示以便选择、查看
国庆时做拼图工具,也需要把原图缩放成界面大小,同时还需要随意割取区域显示到另一个区域,所以,标准canvas又不够用了
所以终于留意到gdi+了
开始以为程序uses gdiplus后,原来标准的canvas的方法就能自动拥有gdi+的效果了
结果,不是这样的。。。。。
于是转为希望仅仅在需要较好处理效果的地方能利用gdi+,
最需要的地方自然是:
1、能加载任意格式的图形文件(本来只能加载bmp/icon/wmf等格式,users jpeg后能加载jpg了,但是gif/png。。。呢)
2、图像的缩放,标准canvas的效果是很差的,gdi+则包含了效果不错的处理算法
3、图像的旋转、对称翻转(jpeg好像只是文件头有对应的标志,而不用真正重新处理整个图像[未确定])
目前只实现了1、2,抛砖引玉,公开源码,请大家看看这个思路对不对,以及实现的方法是不是高效(有没有迂回、冗余了):
Delphi(Pascal) code
unit unitGdiPlus; interface uses classes,Graphics,ExtCtrls,types; function BmpClientRect(bmp:TBitmap):types.Trect; //取bmp的大小到rect,相当于Timage.clientrect function RectWidth(r:types.Trect):Integer; //取rect的宽度,仅仅减少代码 function RectHeight(r:types.Trect):Integer; //取rect的高度,仅仅减少代码 function BmpLoad(bmp:TBitmap;fn:String):Boolean; //把图形文件fn加载到bmp。使用gdi+就可以支持jpg/gif/png等多种图形文件了 function bmpCopy(bmpf,bmpt:Tbitmap;rectf,rectt:types.Trect):Boolean; overload; //把bmpf的rectf区域复制到bmpt的rectt区域,功能与标准的canvas.copyrect一样,只是因为后者的缩放效果太差 function bmpCopy(bmpf,bmpt:Tbitmap):Boolean; overload; //把bmpf的全部复制到bmpt的全部区域,功能与标准的canvas.copyrect一样,只是因为后者的缩放效果太差 function BmpLoadRect(bmp:TBitmap;fn:String;p100:Integer=100):Boolean; overload; //把图形文件fn加载到bmp,按p100/100的比例设置bmp的大小 function BmpLoadRect(bmp:TBitmap;fn:String;p100:Integer;var w,h:Integer):Boolean; overload; //把图形文件fn加载到bmp,按p100/100的比例设置bmp的大小,同时取得图形文件的原始长宽到w,h function BmpLoadRect(bmp:TBitmap;fn:String;r:types.Trect;bScale:Boolean):Boolean; overload; //把图形文件fn加载到bmp的r区域,bScale决定是否保持图形文件的原始长宽比例,否则填满r区域 function BmpLoadRect(bmp:TBitmap;fn:String;r:types.Trect;bScale:Boolean;var w,h:Integer):Boolean; overload; //把图形文件fn加载到bmp的r区域,bScale决定是否保持图形文件的原始长宽比例,否则填满r区域。同时取得图形文件的原始长宽到w,h implementation uses SysUtils,Gdiplus; function RectWidth(r:types.Trect):Integer; Begin result:=r.Right-r.Left+1; End; function RectHeight(r:types.Trect):Integer; Begin result:=r.Bottom-r.Top+1; End; function BmpClientRect(bmp:TBitmap):types.Trect; Begin Result.Left:=0; Result.Top:=0; Result.Right:=bmp.Width-1; Result.Bottom:=bmp.Height-1; End; function BmpLoad(bmp:TBitmap;fn:String):Boolean; var i:Gdiplus.Tgpbitmap; begin Result:=false; if not fileexists(fn) then Exit; try i:=Gdiplus.Tgpbitmap.Create(fn); try bmp.Handle:=i.GetHBITMAP(0); except end; i.Free; Result:=true; except end; end; function bmpCopy(bmpf,bmpt:Tbitmap;rectf,rectt:types.Trect):Boolean; var t:TBitmap; gf,gt:TgpBitmap; g:TGpGraphics; begin result:=false; if (bmpf.Handle=0) or (bmpt.Handle=0) then exit; if (rectwidth(rectf)=rectwidth(rectt)) and (rectheight(rectf)=rectheight(rectt)) then Begin bmpt.Canvas.CopyRect(rectt,bmpf.Canvas,rectf); result:=True; exit; End; t:=TBitmap.Create; t.Width:=rectwidth(rectf); t.Height:=rectheight(rectf); t.Canvas.CopyRect(BmpClientRect(t),bmpf.Canvas,rectf); gf:=TGpBitmap.Create(t.Handle,t.Palette); t.Free; gt:=TGpBitmap.Create(bmpt.Handle,bmpt.Palette); g:=TGpGraphics.Create(gt); g.DrawImage(gf,rectt.Left,rectt.Top,rectwidth(rectt),rectheight(rectt)); bmpt.Handle:=gt.GetHBITMAP(0); gt.Free; gf.Free; g.Free; result:=True; end; function bmpCopy(bmpf,bmpt:Tbitmap):Boolean; overload; var gf,gt:TgpBitmap; g:TGpGraphics; begin result:=false; if (bmpf.Handle=0) or (bmpt.Handle=0) then exit; gf:=TGpBitmap.Create(bmpf.Handle,bmpf.Palette); gt:=TGpBitmap.Create(bmpt.Handle,bmpt.Palette); g:=TGpGraphics.Create(gt); g.DrawImage(gf,0,0,bmpt.Width,bmpt.Height); bmpt.Handle:=gt.GetHBITMAP(0); gt.Free; gf.Free; g.Free; result:=True; End; function BmpLoadRect(bmp:TBitmap;fn:String;p100:Integer;var w,h:Integer):Boolean; overload; var gf,gt:TgpBitmap; g:TGpGraphics; begin Result:=false; if not fileexists(fn) then Exit; gf:=Gdiplus.Tgpbitmap.Create(fn); w:=gf.Width; h:=gf.Height; if (p100<=0) and (bmp.Handle=0) or (p100=100) then Begin bmp.Handle:=gf.GetHBITMAP(0); gf.Free; Result:=true; exit; End; bmp.Width:=gf.Width*p100 div 100; bmp.Height:=gf.Height*p100 div 100; gt:=TGpBitmap.Create(bmp.Handle,bmp.Palette); g:=TGpGraphics.Create(gt); if (p100<=0) then g.DrawImage(gf,0,0,bmp.Width,bmp.Height) else g.DrawImage(gf,0,0,gf.Width*p100 div 100,gf.Height*p100 div 100); bmp.Handle:=gt.GetHBITMAP(0); gt.Free; gf.Free; g.Free; Result:=true; end; function BmpLoadRect(bmp:TBitmap;fn:String;p100:Integer=100):Boolean; var w,h:Integer; Begin Result:=BmpLoadRect(bmp,fn,p100,w,h); End; function BmpLoadRect(bmp:TBitmap;fn:String;r:types.Trect;bScale:Boolean;var w,h:Integer):Boolean; overload; var gf,gt:TgpBitmap; g:TGpGraphics; procedure rerect(); var w,h, rw,rh:Integer; begin rw:=RectWidth(r); rh:=RectHeight(r); Begin w:=(gf.Width)*rh div gf.height; if (w<=rw) then Begin w:=(rw-w) div 2; Inc(r.Left,w); dec(r.Right,w); End else Begin h:=(gf.Height)*rw div gf.Width; h:=(rh-h) div 2; Inc(r.Top,h); dec(r.Bottom,h); End; End; end; begin Result:=false; if not fileexists(fn) then Exit; gf:=Gdiplus.Tgpbitmap.Create(fn); w:=gf.Width; h:=gf.Height; gt:=TGpBitmap.Create(bmp.Handle,bmp.Palette); g:=TGpGraphics.Create(gt); if bScale then reRect(); g.DrawImage(gf,r.Left,r.Top,rectwidth(r),rectheight(r)); bmp.Handle:=gt.GetHBITMAP(0); gt.Free; gf.Free; g.Free; Result:=true; end; function BmpLoadRect(bmp:TBitmap;fn:String;r:types.Trect;bScale:Boolean):Boolean; var w,h:Integer; Begin Result:=BmpLoadRect(bmp,fn,r,bscale,w,h); End; end.
作者: sz_haitao 发布时间: 2011-10-08
沙发,学习
作者: onlyou13 发布时间: 2011-10-08
谢谢,无私奉献。
作者: Terony 发布时间: 2011-10-08
学习,感谢....
作者: dongmei757 发布时间: 2011-10-08
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28