202 lines
5.2 KiB
ObjectPascal

unit blur_main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
ExtCtrls, StdCtrls, BGRABitmap, BGRABitmapTypes, EpikTimer, LMessages,
BGRAGrayscaleMask;
type
{ TForm1 }
TForm1 = class(TForm)
Label_RadiusValueY: TLabel;
Label_RadiusX: TLabel;
Label2: TLabel;
Label_RadiusY: TLabel;
Label_RadiusValueX: TLabel;
Panel1: TPanel;
Radio_Box: TRadioButton;
Radio_Motion: TRadioButton;
Radio_Fast: TRadioButton;
Radio_Corona: TRadioButton;
Radio_Disk: TRadioButton;
Radio_OrientedMotion: TRadioButton;
Radio_Radial: TRadioButton;
TrackBar_BlurRadiusX: TTrackBar;
TrackBar_BlurRadiusY: TTrackBar;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
{%H-}Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
{%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
procedure FormPaint(Sender: TObject);
procedure Radio_Change(Sender: TObject);
procedure TrackBar_BlurRadiusChange(Sender: TObject);
procedure WMEraseBkgnd(var {%H-}Message: TLMEraseBkgnd); message LM_ERASEBKGND;
private
{ private declarations }
procedure UpdateLabelRadius;
public
{ public declarations }
image: TBGRABitmap;
shadowBase: TGrayscaleMask;
timer : TEpikTimer;
movingShadow: boolean;
movingOrigin,shadowOfs: TPoint;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
function ComputeAngle(dx, dy: single): single;
begin
if dy = 0 then
begin
if dx < 0 then result := 180 else result := 0;
end else
if dx = 0 then
begin
if dy < 0 then result := -90 else result := 90;
end else
begin
result := ArcTan(dy/dx)*180/Pi;
if dx < 0 then result += 180;
end;
end;
{ TForm1 }
procedure TForm1.FormPaint(Sender: TObject);
var bmp: TBGRABitmap;
ombre: TGrayscaleMask;
x,y,tx,ty: integer;
blurType: TRadialBlurType;
radiusX,radiusY,len: single;
begin
tx := clientWidth;
ty := Panel1.Top;
bmp := TBGRABitmap.Create(tx,ty,BGRAWhite);
x := (tx-image.Width) div 2;
y := (ty-image.Height) div 2;
radiusX := TrackBar_BlurRadiusX.Position/10;
radiusY := TrackBar_BlurRadiusY.Position/10;
timer.Clear;
timer.Start;
if Radio_Motion.Checked or Radio_OrientedMotion.Checked then
begin
len := sqrt(sqr(radiusX)+sqr(radiusY));
ombre := shadowBase.FilterBlurMotion(len*2,ComputeAngle(radiusX,radiusY),Radio_OrientedMotion.Checked) as TGrayscaleMask;
end else
begin
if Radio_Box.Checked then
begin
blurType := rbBox;
ombre := shadowBase.FilterBlurRadial(radiusX,radiusY,blurType) as TGrayscaleMask;
end else
begin
if Radio_Fast.Checked then blurType := rbFast else
if Radio_Corona.Checked then blurType := rbCorona else
if Radio_Disk.Checked then blurType := rbDisk else
if Radio_Radial.Checked then blurType := rbNormal;
ombre := shadowBase.FilterBlurRadial(radiusX,radiusY,blurType) as TGrayscaleMask;
end;
end;
timer.Stop;
ombre.Rectangle(0,0,ombre.width,ombre.height,TByteMask.New(128));
bmp.FillMask(x+shadowOfs.x,y+shadowOfs.y,ombre,BGRA(64,128,64), dmDrawWithTransparency);
ombre.free;
bmp.PutImage(x,y,image,dmDrawWithTransparency);
bmp.TextOut(0,0,inttostr(round(timer.Elapsed*1000))+' ms',BGRABlack);
bmp.Draw(Canvas,0,0);
bmp.Free;
end;
procedure TForm1.Radio_Change(Sender: TObject);
begin
Invalidate;
end;
procedure TForm1.TrackBar_BlurRadiusChange(Sender: TObject);
begin
UpdateLabelRadius;
Repaint;
end;
procedure TForm1.WMEraseBkgnd(var Message: TLMEraseBkgnd);
begin
//
end;
procedure TForm1.UpdateLabelRadius;
begin
Label_RadiusValueX.Caption := '= '+FloatToStrF(TrackBar_BlurRadiusX.Position/10,ffFixed,7,1);
Label_RadiusValueY.Caption := '= '+FloatToStrF(TrackBar_BlurRadiusY.Position/10,ffFixed,7,1);
Label_RadiusValueX.Update;
Label_RadiusValueY.Update;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
image := TBGRABitmap.Create(160,200);
image.FontName := 'Times New Roman';
image.FontHeight := 300;
image.FontAntialias:= true;
image.TextOut(image.Width div 2,-100,'a',BGRA(128,192,128,255),taCenter);
shadowBase := TGrayscaleMask.Create(image, cAlpha);
UpdateLabelRadius;
timer := TEpikTimer.Create(Self);
shadowOfs := Point(10,10);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
image.free;
shadowBase.free;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
movingOrigin := Point(X,Y);
movingShadow := true;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if movingShadow then
begin
inc(shadowOfs.x, X-movingOrigin.X);
inc(shadowOfs.y, Y-movingOrigin.Y);
movingOrigin := Point(X,Y);
Invalidate;
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
movingShadow:= false;
end;
end.