123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- // SPDX-License-Identifier: GPL-3.0-only
- unit UNewimage;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
- StdCtrls, Spin, Buttons, ComCtrls, ExtCtrls, BGRAVirtualScreen, BGRAShape,
- uimage, LazPaintType, LCScaleDPI, BGRABitmap, BGRABitmapTypes;
- const
- shadowOffsetX = 3;
- shadowOffsetY = 3;
- shadowBlur= 3;
- type
- TLastEnteredValue = (valWidth,valHeight,valRatio);
- { TFNewImage }
- TFNewImage = class(TForm)
- BGRAShape1: TBGRAShape;
- BGRAShape10: TBGRAShape;
- BGRAShape2: TBGRAShape;
- BGRAShape3: TBGRAShape;
- BGRAShape4: TBGRAShape;
- BGRAShape5: TBGRAShape;
- BGRAShape6: TBGRAShape;
- BGRAShape7: TBGRAShape;
- BGRAShape8: TBGRAShape;
- BGRAShape9: TBGRAShape;
- ComboBox_Ratio: TComboBox;
- ComboBox_BitDepth: TComboBox;
- Image1: TImage;
- Label_BitDepth: TLabel;
- Label_MemoryRequiredValue: TLabel;
- Label_Height1: TLabel;
- Label_MemoryRequired: TLabel;
- ToolBar_Rotate: TToolBar;
- ToolButton_Rotate: TToolButton;
- vsPreview: TBGRAVirtualScreen;
- Button_OK: TButton;
- Button_Cancel: TButton;
- Label_Width: TLabel;
- Label_Height: TLabel;
- SpinEdit_Height: TSpinEdit;
- SpinEdit_Width: TSpinEdit;
- procedure BGRAShapeClick(Sender: TObject);
- procedure ComboBox_BitDepthChange(Sender: TObject);
- procedure ComboBox_RatioChange(Sender: TObject);
- procedure ComboBox_RatioEnter(Sender: TObject);
- procedure ComboBox_RatioExit(Sender: TObject);
- procedure SpinEdit_HeightChange(Sender: TObject);
- procedure ToolButton_RotateClick(Sender: TObject);
- procedure vsPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
- procedure Button_OKClick(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormShow(Sender: TObject);
- procedure SpinEdit_WidthChange(Sender: TObject);
- private
- FLastEnteredValue: TLastEnteredValue;
- FRatio: double;
- FRatioWasChanged: boolean;
- FRecomputing: boolean;
- FBackColor: TBGRAPixel;
- procedure UpdatePreview;
- function GetBitDepth: integer;
- public
- LazPaintInstance: TLazPaintCustomInstance;
- ForIcon: boolean;
- newImageResult: TBGRABitmap;
- end;
- function ShowNewImageDlg(AInstance: TLazPaintCustomInstance; AForIcon: boolean; out tx,ty,bpp: integer; out back: TBGRAPixel):boolean;
- implementation
- uses umac, UMySLV, UResourceStrings, UGraph;
- { TFNewImage }
- function ShowNewImageDlg(AInstance: TLazPaintCustomInstance; AForIcon: boolean; out tx,ty,bpp: integer; out back: TBGRAPixel):boolean;
- var
- NewImage: TFNewImage;
- begin
- tx := 0;
- ty := 0;
- result := false;
- NewImage := nil;
- try
- Application.ProcessMessages; //avoid unexpected exit on linux
- NewImage:= TFNewImage.Create(nil);
- NewImage.LazPaintInstance := AInstance;
- NewImage.ForIcon := AForIcon;
- result:= (NewImage.ShowModal = mrOk);
- tx:= NewImage.SpinEdit_Width.Value;
- ty:= NewImage.SpinEdit_Height.Value;
- back:= NewImage.FBackColor;
- bpp := NewImage.GetBitDepth;
- except
- on ex:Exception do
- begin
- AInstance.ShowError('ShowNewImageDlg',ex.Message);
- result := false;
- end;
- end;
- NewImage.free;
- end;
- procedure TFNewImage.Button_OKClick(Sender: TObject);
- begin
- if ForIcon then
- begin
- LazPaintInstance.Config.SetDefaultIconImageWidth(SpinEdit_Width.Value);
- LazPaintInstance.Config.SetDefaultIconImageHeight(SpinEdit_Height.Value);
- LazPaintInstance.Config.SetDefaultIconImageBackgroundColor(FBackColor);
- end else
- begin
- LazPaintInstance.Config.SetDefaultImageWidth(SpinEdit_Width.Value);
- LazPaintInstance.Config.SetDefaultImageHeight(SpinEdit_Height.Value);
- LazPaintInstance.Config.SetDefaultImageBackgroundColor(FBackColor);
- end;
- ModalResult:= mrOk;
- end;
- procedure TFNewImage.vsPreviewRedraw(Sender: TObject;
- Bitmap: TBGRABitmap);
- var
- tx,ty,px,py,x,y: NativeInt;
- ratio: double;
- sx,sy: NativeInt;
- blur: TBGRACustomBitmap;
- begin
- sx := vsPreview.Width- shadowOffsetX - shadowBlur;
- sy := vsPreview.Height- shadowOffsetY - shadowBlur;
- tx := SpinEdit_Width.Value;
- ty := SpinEdit_Height.Value;
- if (tx > 0) and (ty > 0) then
- begin
- ratio := tx/ty;
- if sx/ratio < vsPreview.Height then
- begin
- px := sx;
- py := round(sx/ratio);
- if py <= 0 then py := 1;
- end else
- begin
- px := round(sy*ratio);
- if px <= 0 then px := 1;
- py := sy;
- end;
- x := (sx-px) div 2;
- y := (sy-py) div 2;
- Bitmap.FillRect(x+shadowOffsetX,y+shadowOffsetY,x+shadowOffsetX+px,y+shadowOffsetY+py,BGRA(0,0,0,192),dmDrawWithTransparency);
- blur := bitmap.FilterBlurRadial(shadowBlur,rbFast);
- Bitmap.PutImage(0,0, blur,dmSet);
- blur.free;
- if (px = 1) or (py = 1) then
- Bitmap.FillRect(x,y,x+px,y+py,BGRABlack,dmSet)
- else
- begin
- ugraph.DrawCheckers(Bitmap,rect(x,y,x+px,y+py));
- Bitmap.Rectangle(x,y,x+px,y+py,BGRABlack,FBackColor,dmDrawWithTransparency);
- end;
- end;
- end;
- procedure TFNewImage.ToolButton_RotateClick(Sender: TObject);
- var tx,ty: integer;
- s: string;
- idxCol: integer;
- begin
- if FRecomputing then exit;
- FRecomputing:= true;
- tx := SpinEdit_Width.Value;
- ty := SpinEdit_Height.Value;
- SpinEdit_Width.Value := ty;
- SpinEdit_Height.Value := tx;
- if FRatio <> 0 then
- begin
- FRatio := 1/FRatio;
- s := ComboBox_Ratio.Text;
- idxCol := pos(':',s);
- if idxCol <> 0 then
- begin
- s := copy(s,idxCol+1,length(s)-idxCol)+':'+ copy(s,1,idxCol-1);
- ComboBox_Ratio.Text := s;
- end;
- end;
- FRecomputing:= false;
- if FLastEnteredValue = valWidth then
- FLastEnteredValue:= valHeight else
- if FLastEnteredValue = valHeight then
- FLastEnteredValue:= valWidth;
- UpdatePreview;
- end;
- procedure TFNewImage.ComboBox_RatioChange(Sender: TObject);
- begin
- if FRecomputing then exit;
- FRatio := ComputeRatio(ComboBox_Ratio.Text);
- if FRatio = 0 then exit;
- FRatioWasChanged := true;
- FRecomputing:= true;
- if FLastEnteredValue = valHeight then
- SpinEdit_Width.Value := round(SpinEdit_Height.Value*FRatio)
- else
- SpinEdit_Height.Value := round(SpinEdit_Width.Value/FRatio);
- FRecomputing:= false;
- UpdatePreview;
- end;
- procedure TFNewImage.ComboBox_RatioEnter(Sender: TObject);
- begin
- FRatioWasChanged := false;
- end;
- procedure TFNewImage.ComboBox_RatioExit(Sender: TObject);
- begin
- if FRatioWasChanged then
- FLastEnteredValue := valRatio;
- end;
- procedure TFNewImage.BGRAShapeClick(Sender: TObject);
- begin
- with (Sender as TBGRAShape) do
- FBackColor:= ColorToBGRA(FillColor,FillOpacity);
- UpdatePreview;
- end;
- procedure TFNewImage.ComboBox_BitDepthChange(Sender: TObject);
- begin
- if FRecomputing then exit;
- UpdatePreview;
- end;
- procedure TFNewImage.SpinEdit_HeightChange(Sender: TObject);
- begin
- if FRecomputing then exit;
- FRecomputing:= true;
- if (FLastEnteredValue = valRatio) and (FRatio <> 0) then
- begin
- SpinEdit_Width.Value := round(SpinEdit_Height.Value*FRatio);
- end else
- begin
- FLastEnteredValue:= valHeight;
- FRatio := 0;
- ComboBox_Ratio.Text := '';
- end;
- FRecomputing:= false;
- UpdatePreview;
- end;
- procedure TFNewImage.FormCreate(Sender: TObject);
- begin
- ScaleControl(Self,OriginalDPI);
- FRecomputing := true;
- SpinEdit_Width.MaxValue := MaxImageWidth;
- SpinEdit_Height.MaxValue := MaxImageHeight;
- FLastEnteredValue:= valWidth;
- FRecomputing := false;
- CheckOKCancelBtns(Button_OK,Button_Cancel);
- CheckSpinEdit(SpinEdit_Width);
- CheckSpinEdit(SpinEdit_Height);
- newImageResult := nil;
- end;
- procedure TFNewImage.FormShow(Sender: TObject);
- begin
- ToolBar_Rotate.Images := LazPaintInstance.Icons[DoScaleY(16,OriginalDPI)];
- Label_MemoryRequiredValue.Left := Label_MemoryRequired.BoundsRect.Right + DoScaleX(4,OriginalDPI);
- FRecomputing := true;
- if ForIcon then
- begin
- SpinEdit_Width.Value := LazPaintInstance.Config.DefaultIconImageWidth;
- SpinEdit_Height.Value := LazPaintInstance.Config.DefaultIconImageHeight;
- SpinEdit_Width.Increment := 16;
- SpinEdit_Height.Increment := 16;
- FBackColor:= LazPaintInstance.Config.DefaultIconImageBackgroundColor;
- ToolBar_Rotate.Visible := false;
- Label_BitDepth.Visible := true;
- ComboBox_BitDepth.Visible := true;
- ComboBox_BitDepth.Text := IntToStr(LazPaintInstance.Config.DefaultIconImageBitDepth);
- end else
- begin
- SpinEdit_Width.Value := LazPaintInstance.Config.DefaultImageWidth;
- SpinEdit_Height.Value := LazPaintInstance.Config.DefaultImageHeight;
- SpinEdit_Width.Increment := 10;
- SpinEdit_Height.Increment := 10;
- FBackColor:= LazPaintInstance.Config.DefaultImageBackgroundColor;
- ToolBar_Rotate.Visible := true;
- Label_BitDepth.Visible := false;
- ComboBox_BitDepth.Visible := false;
- ComboBox_BitDepth.Text := '32';
- end;
- if SpinEdit_Width.Value = SpinEdit_Height.Value then
- begin
- ComboBox_Ratio.Text := '1:1';
- FRatio := ComputeRatio(ComboBox_Ratio.Text);
- FLastEnteredValue := valRatio;
- end;
- FRecomputing := false;
- UpdatePreview;
- SafeSetFocus(SpinEdit_Width);
- SpinEdit_Width.SelectAll;
- end;
- procedure TFNewImage.SpinEdit_WidthChange(Sender: TObject);
- begin
- if FRecomputing then exit;
- FRecomputing:= true;
- if (FLastEnteredValue = valRatio) and (FRatio <> 0) then
- begin
- SpinEdit_Height.Value := round(SpinEdit_Width.Value/FRatio);
- end else
- begin
- FLastEnteredValue := valWidth;
- FRatio := 0;
- ComboBox_Ratio.Text := '';
- end;
- FRecomputing:= false;
- UpdatePreview;
- end;
- procedure TFNewImage.UpdatePreview;
- begin
- vsPreview.DiscardBitmap;
- Label_MemoryRequiredValue.Caption := FileSizeToStr(int64((SpinEdit_Width.Value*GetBitDepth+7) div 8)*SpinEdit_Height.Value,rsBytes);
- end;
- function TFNewImage.GetBitDepth: integer;
- begin
- result := StrToInt(ComboBox_BitDepth.Text);
- end;
- {$R *.lfm}
- end.
|