123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- unit MainUnit;
- (* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1 or LGPL 2.1 with linking exception
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Alternatively, the contents of this file may be used under the terms of the
- * Free Pascal modified version of the GNU Lesser General Public License
- * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
- * of this license are applicable instead of those above.
- * Please see the file LICENSE.txt for additional information concerning this
- * license.
- *
- * The Original Code is PixelF Example
- *
- * The Initial Developer of the Original Code is
- * Michael Hansen
- *
- * Portions created by the Initial Developer are Copyright (C) 2000-2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** *)
- interface
- {$include GR32.inc}
- uses
- {$IFNDEF FPC} Windows, {$ELSE} LResources, LCLType, Variants,{$ENDIF}
- SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
- Math, GR32, GR32_LowLevel, GR32_Image, GR32_RangeBars, GR32_Transforms,
- GR32_Blend;
- type
- { TMainForm }
- TMainForm = class(TForm)
- GbrTwist: TGaugeBar;
- Image32: TImage32;
- LblTwirlPower: TLabel;
- PnlSettings: TPanel;
- PnlTwirlDistortion: TPanel;
- RbxGetPixelFS: TRadioButton;
- RbxPixelS: TRadioButton;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure Image32PaintStage(Sender: TObject; Buffer: TBitmap32;
- StageNum: Cardinal);
- procedure GbrTwistChange(Sender: TObject);
- public
- Src: TBitmap32;
- procedure TwirlDistortion(Dst, Srcb: TBitmap32; const Value: Integer);
- end;
- var
- MainForm: TMainForm;
- implementation
- {$R *.dfm}
- uses
- {$IFDEF Darwin}
- MacOSAll,
- {$ENDIF}
- GR32_Math;
- procedure TMainForm.FormCreate(Sender: TObject);
- begin
- // load example image
- Image32.Bitmap.LoadFromResourceName(HInstance, 'STONES', RT_RCDATA);
- with Image32 do
- begin
- if PaintStages[0]^.Stage = PST_CLEAR_BACKGND then PaintStages[0]^.Stage := PST_CUSTOM;
- PaintStages.Add^.Stage := PST_CUSTOM;
- end;
- Image32.BufferOversize := 0;
- Src := TBitmap32.Create;
- with Src do
- begin
- SetBorderTransparent(Src, BoundsRect);
- Assign(Image32.Bitmap);
- OuterColor := clNone32;
- end;
- end;
- procedure TMainForm.FormDestroy(Sender: TObject);
- begin
- Src.Free;
- end;
- procedure TMainForm.TwirlDistortion(Dst, Srcb: TBitmap32; const Value: Integer);
- {twirl algoritm inspired by Patrick Quinn´s remap demo}
- var
- X, Y, DstR, DstB: Integer;
- Center: TFloatPoint;
- Radius, Angle, TwirlAngle, ScaledValue: TFloat;
- CosVal, SinVal: Single;
- begin
- Center.X := Srcb.Width * 0.5;
- Center.Y := Srcb.Height * 0.5;
- ScaledValue := -Value * 0.2 / Srcb.Height;
- DstR := Dst.Width - 1;
- DstB := Dst.Height - 1;
- if RbxGetPixelFS.Checked then
- for Y := 0 to DstB do
- for X := 0 to DstR do begin
- Radius := GR32_Math.Hypot(X - Center.X, Y - Center.Y);
- Angle := ArcTan2(Y - Center.Y, X - Center.X);
- TwirlAngle := Angle + Radius * ScaledValue;
- GR32_Math.SinCos(TwirlAngle, SinVal, CosVal);
- Dst.Pixel[X, Y] := Srcb.PixelFS[Center.X + Radius * CosVal,
- Center.Y + Radius * SinVal];
- end
- else if RbxPixelS.Checked then
- for Y := 0 to DstB do
- for X := 0 to DstR do begin
- Radius := GR32_Math.Hypot(X - Center.X, Y - Center.Y);
- Angle := ArcTan2(Y - Center.Y, X - Center.X);
- TwirlAngle := Angle + Radius * ScaledValue;
- GR32_Math.SinCos(TwirlAngle, SinVal, CosVal);
- Dst.Pixel[X, Y] := Srcb.PixelS[Round(Center.X + Radius * CosVal),
- Round(Center.Y + Radius * SinVal)];
- end;
- end;
- procedure TMainForm.Image32PaintStage(Sender: TObject; Buffer: TBitmap32;
- StageNum: Cardinal);
- const
- Colors: array [0..1] of TColor32 = ($FFFFFFFF, $FFB0B0B0);
- var
- W, I, J, Parity: Integer;
- Line1, Line2: TArrayOfColor32; // a buffer for a couple of scanlines
- begin
- with Image32.Buffer do
- if StageNum = 0 then
- begin
- W := Width;
- SetLength(Line1, W);
- SetLength(Line2, W);
- for I := 0 to W - 1 do
- begin
- Parity := I shr 3 and $1;
- Line1[I] := Colors[Parity];
- Line2[I] := Colors[1 - Parity];
- end;
- for J := 0 to Height - 1 do
- begin
- Parity := J shr 3 and $1;
- if Boolean(Parity) then
- MoveLongword(Line1[0], ScanLine[J]^, W)
- else
- MoveLongword(Line2[0], ScanLine[J]^, W);
- end;
- end
- else
- FrameRectS(BoundsRect , $FF000000);
- end;
- procedure TMainForm.GbrTwistChange(Sender: TObject);
- begin
- with Image32 do
- begin
- TwirlDistortion(Bitmap, Src, GbrTwist.Position);
- GbrTwist.Repaint;
- Repaint;
- end;
- end;
- end.
|