Jelajahi Sumber

more filters

wait for filter thread
johann 5 tahun lalu
induk
melakukan
095501ff6c

+ 35 - 20
lazpaint/dialog/filter/umotionblur.pas

@@ -49,6 +49,7 @@ type
     FQuitQuery: boolean;
     procedure UpdateStep;
     procedure ComputeAngle(X,Y: integer);
+    procedure InitParams;
     procedure PreviewNeeded;
     procedure OnTaskEvent({%H-}ASender: TObject; AEvent: TThreadManagerEvent);
   end;
@@ -71,8 +72,19 @@ begin
   try
     if FMotionBlur.FFilterConnector.ActiveLayer <> nil then
     begin
-      if FMotionBlur.ShowModal = mrOk then result := srOk
-      else result := srCancelledByUser;
+      if Assigned(FMotionBlur.FFilterConnector.Parameters) and
+        FMotionBlur.FFilterConnector.Parameters.Booleans['Validate'] then
+      begin
+        FMotionBlur.InitParams;
+        FMotionBlur.PreviewNeeded;
+        FMotionBlur.FFilterConnector.LazPaintInstance.Wait(@FMotionBlur.FThreadManager.RegularCheck, 50);
+        FMotionBlur.FFilterConnector.ValidateAction;
+        result := srOk;
+      end else
+      begin
+        if FMotionBlur.ShowModal = mrOk then result := srOk
+        else result := srCancelledByUser;
+      end;
     end
     else
       result := srException;
@@ -150,6 +162,26 @@ begin
   PaintBox1.Repaint;
 end;
 
+procedure TFMotionBlur.InitParams;
+begin
+  if Assigned(FVars) and (FVars.IsDefined('Oriented')) then
+    Checkbox_Oriented.Checked := FVars.Booleans['Oriented']
+  else
+    Checkbox_Oriented.Checked := FFilterConnector.LazPaintInstance.Config.DefaultBlurMotionOriented;
+
+  if Assigned(FVars) and (FVars.IsDefined('Distance')) then
+    SpinEdit_Distance.Value := FVars.Floats['Distance']
+  else
+    SpinEdit_Distance.Value := FFilterConnector.LazPaintInstance.Config.DefaultBlurMotionDistance;
+
+  UpdateStep;
+
+  if Assigned(FVars) and (FVars.IsDefined('Angle')) then
+    angle := FVars.Floats['Angle']
+  else
+    angle := FFilterConnector.LazPaintInstance.Config.DefaultBlurMotionAngle;
+end;
+
 procedure TFMotionBlur.PreviewNeeded;
 begin
   FThreadManager.WantPreview(CreateMotionBlurTask(FFilterConnector.BackupLayer,
@@ -191,24 +223,7 @@ end;
 procedure TFMotionBlur.FormShow(Sender: TObject);
 begin
   FQuitQuery := false;
-
-  if Assigned(FVars) and (FVars.IsDefined('Oriented')) then
-    Checkbox_Oriented.Checked := FVars.Booleans['Oriented']
-  else
-    Checkbox_Oriented.Checked := FFilterConnector.LazPaintInstance.Config.DefaultBlurMotionOriented;
-
-  if Assigned(FVars) and (FVars.IsDefined('Distance')) then
-    SpinEdit_Distance.Value := FVars.Floats['Distance']
-  else
-    SpinEdit_Distance.Value := FFilterConnector.LazPaintInstance.Config.DefaultBlurMotionDistance;
-
-  UpdateStep;
-
-  if Assigned(FVars) and (FVars.IsDefined('Angle')) then
-    angle := FVars.Floats['Angle']
-  else
-    angle := FFilterConnector.LazPaintInstance.Config.DefaultBlurMotionAngle;
-
+  InitParams;
   PreviewNeeded;
   Left := FFilterConnector.LazPaintInstance.MainFormBounds.Left;
 end;

+ 24 - 10
lazpaint/dialog/filter/usharpen.pas

@@ -31,7 +31,7 @@ type
     FMode :TSharpenMode;
     FInitializing: boolean;
     FFilterConnector: TFilterConnector;
-    FVars: TVariableSet;
+    procedure InitParams;
     procedure PreviewNeeded;
   end;
 
@@ -49,7 +49,6 @@ begin
   try
     FSharpen.FFilterConnector := AFilterConnector as TFilterConnector;
     FSharpen.FFilterConnector.OnTryStopAction := @FSharpen.OnTryStopAction;
-    FSharpen.FVars:= FSharpen.FFilterConnector.Parameters;
   except
     on ex: exception do
     begin
@@ -59,8 +58,18 @@ begin
     end;
   end;
   try
-    if FSharpen.ShowModal = mrOK then
-      result := srOk else result := srCancelledByUser;
+    if Assigned(FSharpen.FFilterConnector.Parameters) and
+      FSharpen.FFilterConnector.Parameters.Booleans['Validate'] then
+    begin
+      FSharpen.InitParams;
+      FSharpen.PreviewNeeded;
+      FSharpen.FFilterConnector.ValidateAction;
+      result := srOk;
+    end else
+    begin
+      if FSharpen.ShowModal = mrOK then
+        result := srOk else result := srCancelledByUser;
+    end;
   finally
     FSharpen.FFilterConnector.OnTryStopAction := nil;
     FSharpen.Free;
@@ -81,12 +90,7 @@ end;
 procedure TFSharpen.FormShow(Sender: TObject);
 var idxSlash: integer;
 begin
-  FInitializing := true;
-  if Assigned(FVars) and FVars.IsDefined('Amount') then
-    SpinEdit_Amount.Value := round(FVars.Floats['Amount']*100)
-  else
-     SpinEdit_Amount.Value := round(FFilterConnector.LazPaintInstance.Config.DefaultSharpenAmount*100);
-  FInitializing := false;
+  InitParams;
   PreviewNeeded;
   idxSlash:= Pos('/',Caption);
   if idxSlash <> 0 then
@@ -114,6 +118,16 @@ begin
   if self.visible then Close;
 end;
 
+procedure TFSharpen.InitParams;
+begin
+  FInitializing := true;
+  if Assigned(FFilterConnector.Parameters) and FFilterConnector.Parameters.IsDefined('Amount') then
+    SpinEdit_Amount.Value := round(FFilterConnector.Parameters.Floats['Amount']*100)
+  else
+     SpinEdit_Amount.Value := round(FFilterConnector.LazPaintInstance.Config.DefaultSharpenAmount*100);
+  FInitializing := false;
+end;
+
 procedure TFSharpen.PreviewNeeded;
 var filtered: TBGRABitmap;
 begin

+ 31 - 8
lazpaint/dialog/filter/utwirl.pas

@@ -40,6 +40,7 @@ type
     { private declarations }
     FInitializing: boolean;
     FCenter: TPointF;
+    procedure InitParams;
     procedure PreviewNeeded;
     function ComputeFilteredLayer: TBGRABitmap;
   public
@@ -61,8 +62,18 @@ begin
   try
     if FTwirl.FilterConnector.ActiveLayer <> nil then
     begin
-      if FTwirl.showModal = mrOk then result := srOk
-      else result := srCancelledByUser;
+      if Assigned(FTwirl.FilterConnector.Parameters) and
+        FTwirl.FilterConnector.Parameters.Booleans['Validate'] then
+      begin
+        FTwirl.InitParams;
+        FTwirl.FilterConnector.PutImage(FTwirl.ComputeFilteredLayer,False,true);
+        FTwirl.FilterConnector.ValidateAction;
+        result := srOk;
+      end else
+      begin
+        if FTwirl.showModal = mrOk then result := srOk
+        else result := srCancelledByUser;
+      end;
     end
     else
       result := srException;
@@ -80,8 +91,6 @@ begin
   CheckSpinEdit(SpinEdit_Radius);
   CheckSpinEdit(SpinEdit_Angle);
   CheckOKCancelBtns(Button_OK{,Button_Cancel});
-
-  FCenter := PointF(0.5,0.5);
 end;
 
 procedure TFTwirl.FormDestroy(Sender: TObject);
@@ -90,10 +99,7 @@ end;
 
 procedure TFTwirl.FormShow(Sender: TObject);
 begin
-  FInitializing:= true;
-  SpinEdit_Radius.Value := round(FilterConnector.LazPaintInstance.Config.DefaultTwirlRadius);
-  SpinEdit_Angle.Value := round(FilterConnector.LazPaintInstance.Config.DefaultTwirlTurn*360);
-  FInitializing := false;
+  InitParams;
   PreviewNeeded;
   Left := FilterConnector.LazPaintInstance.MainFormBounds.Left;
 end;
@@ -149,6 +155,23 @@ begin
   Button_OK.Enabled := true;
 end;
 
+procedure TFTwirl.InitParams;
+begin
+  FInitializing:= true;
+  SpinEdit_Radius.Value := round(FilterConnector.LazPaintInstance.Config.DefaultTwirlRadius);
+  SpinEdit_Angle.Value := round(FilterConnector.LazPaintInstance.Config.DefaultTwirlTurn*360);
+  FCenter := PointF(0.5,0.5);
+  if Assigned(FilterConnector.Parameters) then
+  with FilterConnector.Parameters do
+  begin
+    if IsDefined('Radius') then SpinEdit_Radius.Value := Floats['Radius'];
+    if IsDefined('Angle') then SpinEdit_Angle.Value:= Floats['Angle'];
+    if IsDefined('CenterXPercent') then FCenter.X := Floats['CenterXPercent']/100;
+    if IsDefined('CenterYPercent') then FCenter.Y := Floats['CenterYPercent']/100;
+  end;
+  FInitializing := false;
+end;
+
 procedure TFTwirl.PreviewNeeded;
 begin
   Timer1.Enabled := false;

+ 26 - 1
lazpaint/lazpaintinstance.pas

@@ -188,7 +188,8 @@ type
     procedure ShowPrintDlg; override;
     function HideTopmost: TTopMostInfo; override;
     procedure ShowTopmost(AInfo: TTopMostInfo); override;
-    procedure UpdateWindows;  override;
+    procedure UpdateWindows; override;
+    procedure Wait(ACheckActive: TCheckFunction; ADelayMs: integer); override;
     procedure ShowCanvasSizeDlg; override;
     procedure ShowRepeatImageDlg; override;
     procedure MoveToolboxTo(X,Y: integer); override;
@@ -1256,6 +1257,30 @@ begin
   {$ENDIF}
 end;
 
+procedure TLazPaintInstance.Wait(ACheckActive: TCheckFunction; ADelayMs: integer);
+var
+  tmi: TTopMostInfo;
+  wasEnabled: Boolean;
+begin
+  tmi := HideTopmost;
+  if Assigned(FMain) then
+  begin
+    wasEnabled := FMain.Enabled;
+    FMain.Enabled:= false;
+  end
+  else wasEnabled := false;
+  try
+    repeat
+      Application.ProcessMessages;
+      sleep(ADelayMs);
+    until not ACheckActive();
+  finally
+    if Assigned(FMain) then
+      FMain.Enabled := wasEnabled;
+    ShowTopmost(tmi);
+  end;
+end;
+
 procedure TLazPaintInstance.NotifyImageChange(RepaintNow: boolean; ARect: TRect);
 begin
   FormsNeeded;

+ 2 - 0
lazpaint/lazpainttype.pas

@@ -138,6 +138,7 @@ type
      defined: boolean;
      toolboxHidden, choosecolorHidden, layerstackHidden, imagelistHidden: NativeInt;
   end;
+  TCheckFunction = function: boolean of object;
 
   { TLazPaintCustomInstance }
 
@@ -269,6 +270,7 @@ type
     function ShowNewImageDlg(out bitmap: TBGRABitmap):boolean; virtual; abstract;
     function ShowResampleDialog(AParameters: TVariableSet):boolean; virtual; abstract;
     procedure UpdateWindows; virtual; abstract;
+    procedure Wait(ACheckActive: TCheckFunction; ADelayMs: integer); virtual; abstract;
     procedure ApplyDocking; virtual; abstract;
     procedure AddColorToPalette(AColor: TBGRAPixel); virtual; abstract;
     procedure RemoveColorFromPalette(AColor: TBGRAPixel); virtual; abstract;

+ 3 - 48
lazpaint/ufilters.pas

@@ -93,32 +93,6 @@ var
       result := AInstance.ShowRadialBlurDlg(FilterConnector, blurType, GetCaption);
   end;
 
-  procedure DoBlurMotion;
-  var
-    oriented: Boolean;
-    distance, angle: Double;
-  begin
-    if GetSkip then
-    begin
-      if AParameters.IsDefined('Oriented') then
-        oriented := AParameters.Booleans['Oriented']
-      else oriented := AInstance.Config.DefaultBlurMotionOriented;
-
-      if AParameters.IsDefined('Distance') then
-        distance := AParameters.Floats['Distance']
-      else distance := AInstance.Config.DefaultBlurMotionDistance;
-
-      if AParameters.IsDefined('Angle') then
-        angle := AParameters.Floats['Angle']
-      else angle := AInstance.Config.DefaultBlurMotionAngle;
-
-      filteredLayer := FilterConnector.ActiveLayer.FilterBlurMotion(FilterConnector.WorkArea,
-                          distance,angle,oriented) as TBGRABitmap
-    end
-    else
-      result := AInstance.ShowMotionBlurDlg(FilterConnector);
-  end;
-
   procedure DoMetalFloor;
   var temp: TBGRABitmap;
   begin
@@ -127,21 +101,6 @@ var
      temp.Free;
   end;
 
-  procedure DoSharpen;
-  var
-    amount: single;
-  begin
-    if GetSkip then
-    begin
-      if AParameters.IsDefined('Amount') then
-        amount := AParameters.Floats['Amount']
-      else amount := AInstance.Config.DefaultSharpenAmount;
-      filteredLayer := FilterConnector.ActiveLayer.FilterSharpen(FilterConnector.WorkArea,amount) as TBGRABitmap;
-      AParameters.Floats['Amount'] := amount;
-    end
-    else result := AInstance.ShowSharpenDlg(FilterConnector);
-  end;
-
 var
   layer: TBGRABitmap;
   applyOfsBefore: Boolean;
@@ -172,7 +131,7 @@ begin
 
     filteredLayer := nil;
     case filter of
-    pfSharpen: DoSharpen;
+    pfSharpen: result := AInstance.ShowSharpenDlg(FilterConnector);
     pfSmooth: filteredLayer := layer.FilterSmooth as TBGRABitmap;
     pfClearTypeInverse: filteredLayer := ClearTypeInverseFilter(layer) as TBGRABitmap;
     pfClearType: filteredLayer := ClearTypeFilter(layer) as TBGRABitmap;
@@ -197,7 +156,7 @@ begin
         FilterComplementaryColor(filteredLayer,FilterConnector.WorkArea);
       end;
     pfBlurPrecise, pfBlurRadial, pfBlurCorona, pfBlurDisk, pfBlurFast, pfBlurBox: DoSimpleBlur;
-    pfBlurMotion: DoBlurMotion;
+    pfBlurMotion: result := AInstance.ShowMotionBlurDlg(FilterConnector);
     pfBlurCustom: DoBlurCustom;
     pfEmboss: result := AInstance.ShowEmbossDlg(FilterConnector);
     pfRain: result := AInstance.ShowRainDlg(FilterConnector);
@@ -205,11 +164,7 @@ begin
     pfFunction: result := AInstance.ShowFunctionFilterDlg(FilterConnector);
     pfNoise: result := AInstance.ShowNoiseFilterDlg(FilterConnector);
     pfPixelate: result := AInstance.ShowPixelateDlg(FilterConnector);
-    pfTwirl:
-        if GetSkip then
-          filteredLayer := layer.FilterTwirl(FilterConnector.WorkArea, Point(layer.Width div 2,layer.Height div 2), AInstance.Config.DefaultTwirlRadius, AInstance.Config.DefaultTwirlTurn ) as TBGRABitmap
-        else
-          result := AInstance.ShowTwirlDlg(FilterConnector);
+    pfTwirl: result := AInstance.ShowTwirlDlg(FilterConnector);
     pfWaveDisplacement:
         if GetSkip then
           filteredLayer := ugraph.WaveDisplacementFilter(layer,FilterConnector.WorkArea, PointF(layer.Width/2,layer.Height/2), AInstance.Config.DefaultWaveDisplacementWavelength, AInstance.Config.DefaultWaveDisplacementAmount, AInstance.Config.DefaultWaveDisplacementPhase ) as TBGRABitmap

+ 3 - 2
lazpaint/ufilterthread.pas

@@ -34,7 +34,7 @@ type
     destructor Destroy; override;
     procedure WantPreview(ATask: TFilterTask);
     procedure Quit;
-    procedure RegularCheck;
+    function RegularCheck: boolean;
     property Quitting: boolean read FQuitting;
     property ReadyToClose: boolean read GetReadyToClose;
     property CancellingPreview: boolean read FCancellingPreview;
@@ -195,7 +195,7 @@ begin
   FreeAndNil(FNextTask);
 end;
 
-procedure TFilterThreadManager.RegularCheck;
+function TFilterThreadManager.RegularCheck: boolean;
 var filteredLayer: TBGRABitmap;
   currentY: integer;
   changedBounds: TRect;
@@ -219,6 +219,7 @@ begin
   begin
     if not FCancellingPreview then StartNextTask;
   end;
+  result := Assigned(FThread);
 end;
 
 { TFilterThread }

+ 2 - 0
lazpaintscripts/lazpaint/filter.py

@@ -99,3 +99,5 @@ def posterize(levels=None, by_lightness=None, validate=True):
 def phong(color_source=None, altitude_percent=None, altitude_source=None, light_x_percent=None, light_y_percent=None, validate=True):
   command.send("Filter", Name=PHONG, ColorSource=color_source, AltitudePercent=altitude_percent, AltitudeSource=altitude_source, LightXPercent=light_x_percent, LightYPercent=light_y_percent, Validate=validate)
 
+def twirl(radius=None, angle=None, center_x_percent=None, center_y_percent=None, validate=True):
+  command.send("Filter", Name=TWIRL, Radius=radius, Angle=angle, CenterXPercent=center_x_percent, CenterYPercent=center_y_percent, Validate=validate)

+ 5 - 3
lazpaintscripts/test_filter.py

@@ -1,8 +1,10 @@
 from lazpaint import filter, image
 
-filter.filter_function(green="green*2")
+#filter.filter_function(green="green*2")
 #filter.phong(color_source=filter.PHONG_COLOR_LAYER, light_x_percent=20, light_y_percent=20, altitude_percent=30, altitude_source=filter.PHONG_ALTITUDE_ALPHA_CHANNEL)
-filter.emboss(angle=45, transparent=False, preserve_colors=True)
+#filter.emboss(angle=45, transparent=False, preserve_colors=True)
 #filter.noise(grayscale=True, opacity=128)
 #filter.pixelate(20, filter.PIXELATE_QUALITY_BEST)
-
+#filter.twirl(radius=min(image.get_width(),image.get_height())/2, angle=360)
+#filter.blur_motion(50, 45, True)
+filter.sharpen(1)