delphi JPG圖片 旋轉 切邊 縮放

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、切邊是指對應的邊去除設定值,縮放則爲處理後的目標值不大於設定值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章