unit UCutFigure_JPG; //JPG 切图 interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,Math, jpeg ; //向左旋转X度 procedure Rotate(Srcbmp, DestBmp: TBitmap; dbTheta: Double); //毫米单位转换为英寸单位 function MmToInch(Length: Extended): Extended; //英寸单位转换为毫米单位 function InchToMm(Length: Extended): Extended; function CutFigure_JPG(图片文件名:string;旋转角度:integer;切边_上,切边_下,切边_左,切边_右:real;缩放_宽,缩放_高:real):Integer; implementation function CutFigure_JPG(图片文件名:string;旋转角度:integer;切边_上,切边_下,切边_左,切边_右:real;缩放_宽,缩放_高:real):Integer; var JpgSrc,JpgDest : TJpegImage; BmpSrc, BmpDest: TBitmap; F_上,F_下,F_左,F_右,F_长,F_宽:integer;//切边值 F_缩放比率:real; F_处理状态:boolean; begin //文件名,含全路径 if not FileExists(图片文件名) then exit;//文件不存在则退出 JpgSrc := TJpegImage.Create; JpgDest:=TJpegImage.Create ; BmpSrc:=TBitmap.Create; BmpDest:=TBitmap.Create ; JpgSrc.LoadFromFile(图片文件名);//加载文件 BmpSrc.Assign(JpgSrc); F_处理状态:=False;//未处理过 if 旋转角度>0 then begin Rotate(BmpSrc, BmpDest,旋转角度); //由于函数是左向旋转,所以这里角度设置为270。 F_处理状态:=true; end; if (切边_上>0) or (切边_下>0) or (切边_左>0) or (切边_右>0) then begin //需要切边 if F_处理状态=true then BmpSrc.Assign(BmpDest); //切边传进来的参数,为cm if 切边_上<0 then 切边_上:=0; if 切边_下<0 then 切边_下:=0; if 切边_左<0 then 切边_左:=0; if 切边_右<0 then 切边_右:=0; F_上:=Round(MmToInch(切边_上)*10*96); F_下:=Round(MmToInch(切边_下)*10*96); F_左:=Round(MmToInch(切边_左)*10*96); F_右:=Round(MmToInch(切边_右)*10*96); if (F_上+F_下<BmpSrc.Height) and (F_左+F_右>=BmpSrc.Width ) then begin //值超范围,不处理 BmpDest.Height:=BmpSrc.Height-(F_上+F_下); BmpDest.Width:=BmpSrc.Width-(F_左+F_右); SetStretchBltMode(BmpDest.Canvas.Handle,HALFTONE);//设置指位图拉伸模式 stretchblt(BmpDest.Canvas.Handle,0,0,BmpDest.Width,BmpDest.Height,BmpSrc.Canvas.Handle,F_左,F_上,BmpDest.Width,BmpDest.Height,srccopy); //从源矩形中复制一个位图到目标矩形并适当压缩 F_处理状态:=true; end ; end; if (缩放_高>0) or (缩放_宽>0) then begin //需要缩放 if F_处理状态=true then BmpSrc.Assign(BmpDest); F_长:=Round(MmToInch(缩放_高)*10*96); F_宽:=Round(MmToInch(缩放_宽)*10*96); if (F_长>0) and (F_宽>0) and (BmpSrc.Height>F_长) and (BmpSrc.Width >F_宽) then begin //如果都超过,则等比缩小到其中较大的一个值等于目标值 if (F_长/BmpSrc.Height)>(F_宽/BmpSrc.Width) then begin F_缩放比率:=F_宽/BmpSrc.Width; end else begin F_缩放比率:=F_长/BmpSrc.Height; end; end else if (F_长>0) and (BmpSrc.Height>F_长) then begin F_缩放比率:=F_长/BmpSrc.Height; end else if (F_宽>0) and (BmpSrc.Width >F_宽) then begin F_缩放比率:=F_宽/BmpSrc.Width; end else begin F_缩放比率:=-1;//如果没取到值,或原图已经小于设定值则不处理 end; if F_缩放比率>0 then begin BmpDest.Height:=Round(BmpSrc.Height*F_缩放比率); BmpDest.Width:=Round(BmpSrc.Width *F_缩放比率); SetStretchBltMode(BmpDest.Canvas.Handle,HALFTONE);//设置指位图拉伸模式 stretchblt(BmpDest.Canvas.Handle,0,0,BmpDest.Width,BmpDest.Height,BmpSrc.Canvas.Handle,0,0,BmpSrc.Width,BmpSrc.Height,srccopy); //从源矩形中复制一个位图到目标矩形并适当压缩 F_处理状态:=true; end; end; if F_处理状态=true then begin //处理后,保存图片 JpgDest.CompressionQuality := 100; JpgDest.Assign(BmpDest); JpgDest.SaveToFile(图片文件名); end; JpgSrc.Free; JpgDest.free; BmpSrc.Free; BmpDest.Free; end; procedure Rotate(Srcbmp, DestBmp: TBitmap; dbTheta: Double);//此过程是网上找的,不记得原博文地址了,抱歉 var ptOrgCenter, ptTarCenter, ptc: TPoint; pta: array[0..3] of TPoint; ba: array[0..3] of integer; i: integer; function RotateXY(dbTheda: double; p1: TPoint): TPoint; var dbA: double; _cosA, _sinA, _dbLastT: double; begin _dbLastT := -99999.999; _cosA :=0.0; _sinA :=0.0; if dbTheda <> _dbLastT then begin dbA := dbTheda * Pi / 180; _sinA := sin(dbA); _cosA := cos(dbA); _dbLastT := dbTheda; end; Result.x := round(p1.x * _cosA + p1.y * _sinA); Result.y := round(-p1.x * _sinA + p1.y * _cosA); end; begin ptOrgCenter.x := Srcbmp.Width div 2; ptOrgCenter.y := Srcbmp.Height div 2; pta[0] := RotateXY(dbTheta,Point(0, 0)); //这里不知道原来为何减1 {pta[1]:=RotateXY(dbTheta,Point(Srcbmp.Width - 1, 0)); pta[2]:=RotateXY(dbTheta,Point(0, Srcbmp.Height - 1)); pta[3]:=RotateXY(dbTheta,Point(Srcbmp.Width - 1, Srcbmp.Height - 1)); } pta[1] := RotateXY(dbTheta,Point(Srcbmp.Width, 0)); pta[2] := RotateXY(dbTheta,Point(0, Srcbmp.Height)); pta[3] := RotateXY(dbTheta,Point(Srcbmp.Width, Srcbmp.Height)); DestBmp.PixelFormat := pf32bit; DestBmp.Canvas.Brush.Color := clWindow; for i := 0 to 3 do ba[i] := pta[i].x; DestBmp.width := MaxIntValue(ba) - MinIntValue(ba); for i := 0 to 3 do ba[i] := pta[i].y; DestBmp.Height := MaxIntValue(ba) - MinIntValue(ba); ptc := RotateXY(dbTheta, Point(Srcbmp.Width div 2, Srcbmp.Height div 2)); ptTarCenter.x := DestBmp.Width div 2; ptTarCenter.y := DestBmp.Height div 2; pta[0].x := pta[0].x + ptTarCenter.x - ptc.x; pta[0].y := pta[0].y + ptTarCenter.y - ptc.y; pta[1].x := pta[1].x + ptTarCenter.x - ptc.x; pta[1].y := pta[1].y + ptTarCenter.y - ptc.y; pta[2].x := pta[2].x + ptTarCenter.x - ptc.x; pta[2].y := pta[2].y + ptTarCenter.y - ptc.y; if PlgBlt(DestBmp.Canvas.Handle, pta, Srcbmp.Canvas.Handle, 0, 0, Srcbmp.Width - 1, Srcbmp.Height - 1, 0, 0, 0) then DestBmp.Canvas.Draw(0, 0, DestBmp) else DestBmp.Canvas.TextOut(0,0,‘只支持WinNT内核操作系统.‘); end; //毫米单位转换为英寸单位 function MmToInch(Length: Extended): Extended; begin Result := Length/25.4; end; //英寸单位转换为毫米单位 function InchToMm(Length: Extended): Extended; begin Result := Length*25.4; end; end.
用中文参数变量,别笑,这样只是为了让大家更好的解读一些重点代码。
注意我这儿的图片质量,都用了高质量,如果觉得处理的大小太大,则可以降低质量来获得小一些的文件
注意:
1、参数值为0时,表示该项不处理。
2、处理为依次执行,即旋转、切边、缩放,后一项的参数,也应参考前一项,而非原图参数
3、缩放只支持等比缩放,也就是只会根据宽或高中的一个值进行缩放,根据哪一个值,则适用于大值等于设置值的处理原则。
4、切边是指对应的边去除设定值,缩放则为处理后的目标值不大于设定值。