{

   This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit UfrmEffect_Resize;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UfrmEffectBase, StdCtrls, ExtCtrls, GR32, GR32_Resamplers, gr32_transforms,
  Mask;

type
  TfrmEffect_Resize = class(TfrmEffectBase)
    Panel1: TPanel;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label7: TLabel;
    ActWidEdit: TEdit;
    ActHeiEdit: TEdit;
    RatioEdit: TEdit;
    RatioCheckBox: TCheckBox;
    GroupBox2: TGroupBox;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    ActHPercEdit: TEdit;
    ActVPercEdit: TEdit;
    SynchronCheck: TCheckBox;
    GroupBox3: TGroupBox;
    TypeCombo: TComboBox;
    Label8: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure ActWidEditKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ActHeiEditKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure RatioEditKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ActHPercEditKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ActVPercEditKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
    FOrgWidth:Integer;
    FOrgHeight:Integer;
    FWidth:Integer;
    FHeight:Integer;
    FHPercent:Integer;
    FVPercent:Integer;
    FRatio:Double;
    procedure Resample(Src, Dst: TBitmap32; X, Y: Integer; Filter: TStretchFilter);
    procedure ActualizeValues;
    procedure ActualizeValues2;
    procedure ok_select; override;
    procedure set_effectapply;
    procedure imageprocess(var src:tbitmap);
  public
    { Public declarations }
  end;

var
  frmEffect_Resize: TfrmEffect_Resize;

implementation
uses Uconfig, Ufrmmain;
{$R *.dfm}

procedure TfrmEffect_Resize.FormCreate(Sender: TObject);
begin
  inherited;
  self.Width:=630;
  self.Height:=380;
  Panel1.Align:=alclient;
  PanelPreView.Align:=alLeft;
end;

procedure TfrmEffect_Resize.Resample(Src,Dst: TBitmap32; X,Y: Integer; Filter:TStretchFilter);
var
  RectS: TRect;
  RectD: TRect;
  DstClipW,DstClipH:Trect;
  resampler:TCustomResampler;
Begin
  //(NearestFilter, LinearFilter,SplineFilter, LanczosFilter, MitchellFilter);
  RectS.Top := 0;
  RectS.Left := 0;
  RectS.Right := src.Width;
  RectS.Bottom := src.Height;
  RectD.Top := 0;
  RectD.Left := 0;
  RectD.Right := X;
  RectD.Bottom := Y;
  //DstClipW := DstClip.Right - DstClip.Left;
  //DstClipH := DstClip.Bottom - DstClip.Top;
  Dst.Clear(clGray32);
  Dst.Width:=X;
  Dst.Height:=Y;

  case Filter of
    sfNearest:resampler:=TNearestResampler.Create;
    sfDraft:resampler:=TDraftResampler.Create;
    sfLinear:resampler:=TLinearResampler.Create;
  else
    resampler:=TKernelResampler.Create;
    with resampler as TKernelResampler do
      case Filter of
        sfCosine: Kernel := TCosineKernel.Create;
        sfSpline: Kernel := TSplineKernel.Create;
        sfLanczos: Kernel := TLanczosKernel.Create;
        sfMitchell: Kernel := TMitchellKernel.Create;
      end;
  end;
  try
    StretchTransfer(Dst, RectD, RectD, Src, RectS, resampler, dmCustom, nil);
  finally
    resampler.Free;
  end;
end;

procedure TfrmEffect_Resize.ActualizeValues;
begin
  ActHPercEdit.Text:=IntToStr(FHPercent);
  ActVPercEdit.Text:=IntToStr(FVPercent);
  if RatioCheckBox.Checked then begin
    ActWidEdit.Text:=IntToStr(FWidth);
    ActHeiEdit.Text:=IntToStr(FHeight);
  end;
  RatioEdit.Text:=FloatToStr(FRatio);
end;

procedure TfrmEffect_Resize.ActualizeValues2;
begin
  ActHPercEdit.Text:=IntToStr(FHPercent);
  ActVPercEdit.Text:=IntToStr(FVPercent);
  ActWidEdit.Text:=IntToStr(FWidth);
  ActHeiEdit.Text:=IntToStr(FHeight);
  RatioEdit.Text:=FloatToStr(FRatio);
end;

procedure TfrmEffect_Resize.FormShow(Sender: TObject);
var
  key:word;
begin
  make_thumbimage;
  imagepreview1.Bitmap.Assign(thumb_bitmap32);

  FOrgWidth:=org_bitmap32.Width;
  FOrgHeight:=org_bitmap32.Height;
  FRatio:=org_bitmap32.Width / org_bitmap32.Height;

{  FWidth:=FOrgWidth;
  FHeight:=FOrgHeight;
  FHPercent:=100;
  FVPercent:=100;
  ActualizeValues;
}

  label8.Caption:=format('¿øº»Å©±â %d X %d',[FOrgWidth, FOrgHeight]);

  TypeCombo.ItemIndex:=config.getvaluebyinteger('resize_type',3);
  SynchronCheck.Checked:=boolean(config.getvaluebyinteger('resize_SynchronCheck',1));

  RatioCheckBox.Checked:=boolean(config.getvaluebyinteger('resize_RatioCheckBox',1));
  ActWidEdit.Text:=config.getvaluebystring('resize_ActWidEdit','800');
  if RatioCheckBox.Checked=false then
    ActHeiEdit.Text:=config.getvaluebystring('resize_ActHeiEdit','600');

  key:=0;
  ActWidEditKeyUp(ActWidEdit,key,[]);
  ActHeiEditKeyUp(ActHeiEdit,key,[]);

  ActWidEdit.Text:=config.getvaluebystring('resize_ActWidEdit','800');
  ActWidEditKeyUp(ActWidEdit,key,[]);

  applyselect.Visible:=true;
end;

procedure TfrmEffect_Resize.set_effectapply;
begin
end;

procedure TfrmEffect_Resize.ok_select;
var
  Bitmap:tbitmap32;
begin
  config.setvaluebyinteger('resize_type',TypeCombo.ItemIndex);
  config.setvaluebystring('resize_ActWidEdit',ActWidEdit.Text);
  config.setvaluebyinteger('resize_SynchronCheck',integer(SynchronCheck.Checked));
  config.setvaluebyinteger('resize_RatioCheckBox',integer(RatioCheckBox.Checked));
  if RatioCheckBox.Checked=false then
    config.setvaluebystring('resize_ActHeiEdit',ActHeiEdit.Text);

  if applyselect.ItemIndex=0 then begin
    Screen.Cursor:=crHourglass;
    try
      case TypeCombo.ItemIndex of
        0:Resample(org_bitmap32,imagepreview1.Bitmap,FWidth,Fheight,sfNearest);
        1:Resample(org_bitmap32,imagepreview1.Bitmap,FWidth,Fheight,sfLinear);
        2:Resample(org_bitmap32,imagepreview1.Bitmap,FWidth,Fheight,sfSpline);
        3:Resample(org_bitmap32,imagepreview1.Bitmap,FWidth,Fheight,sfLanczos);
        4:Resample(org_bitmap32,imagepreview1.Bitmap,FWidth,Fheight,sfMitchell);
      end;
    finally
      screen.Cursor:=crdefault;
    end;
    exit;
  end;
  frmmain.apply_listimages(applyselect.ItemIndex=1,imageprocess,etResize,self.Caption);
  self.ModalResult:=mrcancel;
end;

procedure TfrmEffect_Resize.imageprocess(var src:tbitmap);
var
  Bitmap:TBitmap32;
begin
  org_bitmap32.Assign(src);

  FWidth:=StrToIntdef(ActWidEdit.Text,0);
  if RatioCheckBox.Checked then
    Fheight:=Round(FWidth / (org_bitmap32.Width / org_bitmap32.Height))
  else
    Fheight:=StrToIntdef(ActHeiEdit.Text,0);

  Bitmap:=tbitmap32.Create;
  try
   case TypeCombo.ItemIndex of
    0:Resample(org_bitmap32,Bitmap,FWidth,Fheight,sfNearest);
    1:Resample(org_bitmap32,Bitmap,FWidth,Fheight,sfLinear);
    2:Resample(org_bitmap32,Bitmap,FWidth,Fheight,sfSpline);
    3:Resample(org_bitmap32,Bitmap,FWidth,Fheight,sfLanczos);
    4:Resample(org_bitmap32,Bitmap,FWidth,Fheight,sfMitchell);
   end;
   Bitmap.AssignTo24(src);
  finally
   Bitmap.Free;
  end;
end;

procedure TfrmEffect_Resize.ActWidEditKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Sender as TEdit).Text<>'' then
  begin
    FWidth:=StrToIntdef(ActWidEdit.Text,0);
    if RatioCheckBox.Checked then
    begin
      FHeight:=Round(FWidth / FRatio);
    end;
    FHPercent:=round(FWidth / (FOrgWidth / 100));
    FVPercent:=round(FHeight / (FOrgHeight / 100));
    ActualizeValues;
  end;
end;

procedure TfrmEffect_Resize.ActHeiEditKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Sender as TEdit).Text<>'' then
  begin
    FHeight:=StrToIntdef(ActHeiEdit.Text,0);
    if RatioCheckBox.Checked then
    begin
      FWidth:=Round(FHeight*FRatio);
    end;
    FHPercent:=round(FWidth / (FOrgWidth / 100));
    FVPercent:=round(FHeight / (FOrgHeight / 100));
    ActualizeValues;
  end;
end;

procedure TfrmEffect_Resize.RatioEditKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Sender as TEdit).Text<>'' then
  FRatio:=StrToFloat(RatioEdit.Text);
  FHeight:=Round(FWidth / FRatio);
  FHPercent:=round(FWidth / (FOrgWidth / 100));
  FVPercent:=round(FHeight / (FOrgHeight / 100));
  ActualizeValues;
end;

procedure TfrmEffect_Resize.ActHPercEditKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if (Sender as TEdit).Text<>'' then
  begin
    FHPercent:=StrToIntdef(ActHPercEdit.Text,0);
    if SynchronCheck.Checked then begin
      FVpercent:=FHPercent;
    end;
    FWidth:=Round((FOrgWidth / 100)*FHPercent);
    Fheight:=Round((FOrgHeight / 100)*FVPercent);
    ActualizeValues2;
  end;
end;

procedure TfrmEffect_Resize.ActVPercEditKeyUp(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if (Sender as TEdit).Text<>'' then
  begin
    FVPercent:=StrToIntdef(ActVPercEdit.Text,0);
    if SynchronCheck.Checked then begin
      FHpercent:=FVPercent;
    end;
    FWidth:=Round((FOrgWidth / 100)*FHPercent);
    Fheight:=Round((FOrgHeight / 100)*FVPercent);
    ActualizeValues2;
  end;
end;

end.
