delphi JPG圖片 旋轉 切邊 縮放
阿新 • • 發佈:2018-03-22
mini 文件 ctr 根據 gin function HA assign procedure
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、切邊是指對應的邊去除設定值,縮放則為處理後的目標值不大於設定值。
delphi JPG圖片 旋轉 切邊 縮放