首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

初次接触GDI+,做了一个工具函数库。抛砖引玉,公开源码,请大家看看这个思路对不对,以及实现的方法是不是高效解决方案

2012-03-08 
初次接触GDI+,做了一个工具函数库。抛砖引玉,公开源码,请大家看看这个思路对不对,以及实现的方法是不是高效

初次接触GDI+,做了一个工具函数库。抛砖引玉,公开源码,请大家看看这个思路对不对,以及实现的方法是不是高效
以前做过一个批量缩小照片的工具,因为标准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
unit unitGdiPlus;interfaceuses classes,Graphics,ExtCtrls,types;function BmpClientRect(bmp:TBitmap):types.Trect; //取bmp的大小到rect,相当于Timage.clientrectfunction 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,hfunction 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,himplementationuses 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. 



[解决办法]
沙发,学习
[解决办法]
谢谢,无私奉献。
[解决办法]
学习,感谢....
[解决办法]
mark....
[解决办法]
为什么不建一个类呢?
[解决办法]
学习学习
[解决办法]
mark....
[解决办法]
学习。。。。
[解决办法]
万一老师那里有很详细的 GDI 教程
[解决办法]
路过支持一下,这些东东偶以前到都做过,呵呵
[解决办法]
mark
[解决办法]
缩放变形的 都会 影响图像质量的。。
[解决办法]
换FireMonkey后发现这些问题都不是问题了,妈的,又一堆新问题……

热点排行