fMainD.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. unit fMainD;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is PixelF Example
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Michael Hansen
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2005
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$I GR32.inc}
  35. uses
  36. {$IFNDEF FPC} Windows, {$ELSE} LResources, Variants,{$ENDIF}
  37. SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
  38. Math, GR32, GR32_LowLevel, GR32_Image, GR32_RangeBars, GR32_Transforms,
  39. GR32_Blend;
  40. type
  41. { TMainForm }
  42. TMainForm = class(TForm)
  43. GbrTwist: TGaugeBar;
  44. Image32: TImage32;
  45. LblTwirlPower: TLabel;
  46. PnlSettings: TPanel;
  47. PnlTwirlDistortion: TPanel;
  48. RbxGetPixelFS: TRadioButton;
  49. RbxPixelS: TRadioButton;
  50. procedure FormCreate(Sender: TObject);
  51. procedure FormDestroy(Sender: TObject);
  52. procedure Image32PaintStage(Sender: TObject; Buffer: TBitmap32;
  53. StageNum: Cardinal);
  54. procedure GbrTwistChange(Sender: TObject);
  55. public
  56. Src: TBitmap32;
  57. procedure TwirlDistortion(Dst, Srcb: TBitmap32; const Value: Integer);
  58. end;
  59. var
  60. MainForm: TMainForm;
  61. implementation
  62. {$IFDEF FPC}
  63. {$R *.lfm}
  64. {$ELSE}
  65. {$R *.dfm}
  66. {$ENDIF}
  67. uses
  68. GR32_Math,
  69. {$IFDEF Darwin}
  70. MacOSAll,
  71. {$ENDIF}
  72. {$IFNDEF FPC}
  73. JPEG;
  74. {$ELSE}
  75. LazJPG;
  76. {$ENDIF}
  77. procedure TMainForm.FormCreate(Sender: TObject);
  78. var
  79. ResStream: TResourceStream;
  80. JPEG: TJPEGImage;
  81. begin
  82. // load example image
  83. JPEG := TJPEGImage.Create;
  84. try
  85. ResStream := TResourceStream.Create(HInstance, 'Stones', RT_RCDATA);
  86. try
  87. JPEG.LoadFromStream(ResStream);
  88. finally
  89. ResStream.Free;
  90. end;
  91. Image32.Bitmap.Assign(JPEG);
  92. finally
  93. JPEG.Free;
  94. end;
  95. with Image32 do
  96. begin
  97. if PaintStages[0]^.Stage = PST_CLEAR_BACKGND then PaintStages[0]^.Stage := PST_CUSTOM;
  98. PaintStages.Add^.Stage := PST_CUSTOM;
  99. end;
  100. Image32.BufferOversize := 0;
  101. Src := TBitmap32.Create;
  102. with Src do
  103. begin
  104. SetBorderTransparent(Src, BoundsRect);
  105. Assign(Image32.Bitmap);
  106. OuterColor := $00000000;
  107. end;
  108. end;
  109. procedure TMainForm.FormDestroy(Sender: TObject);
  110. begin
  111. Src.Free;
  112. end;
  113. procedure TMainForm.TwirlDistortion(Dst, Srcb: TBitmap32; const Value: Integer);
  114. {twirl algoritm inspired by Patrick Quinn´s remap demo}
  115. var
  116. X, Y, DstR, DstB: Integer;
  117. Center: TFloatPoint;
  118. Radius, Angle, TwirlAngle, ScaledValue: TFloat;
  119. CosVal, SinVal: Single;
  120. begin
  121. Center.X := Srcb.Width * 0.5;
  122. Center.Y := Srcb.Height * 0.5;
  123. ScaledValue := -Value * 0.2 / Srcb.Height;
  124. DstR := Dst.Width - 1;
  125. DstB := Dst.Height - 1;
  126. if RbxGetPixelFS.Checked then
  127. for Y := 0 to DstB do
  128. for X := 0 to DstR do begin
  129. Radius := Hypot(X - Center.X, Y - Center.Y);
  130. Angle := ArcTan2(Y - Center.Y, X - Center.X);
  131. TwirlAngle := Angle + Radius * ScaledValue;
  132. GR32_Math.SinCos(TwirlAngle, SinVal, CosVal);
  133. Dst.Pixel[X, Y] := Srcb.PixelFS[Center.X + Radius * CosVal,
  134. Center.Y + Radius * SinVal];
  135. end
  136. else if RbxPixelS.Checked then
  137. for Y := 0 to DstB do
  138. for X := 0 to DstR do begin
  139. Radius := Hypot(X - Center.X, Y - Center.Y);
  140. Angle := ArcTan2(Y - Center.Y, X - Center.X);
  141. TwirlAngle := Angle + Radius * ScaledValue;
  142. GR32_Math.SinCos(TwirlAngle, SinVal, CosVal);
  143. Dst.Pixel[X, Y] := Srcb.PixelS[Round(Center.X + Radius * CosVal),
  144. Round(Center.Y + Radius * SinVal)];
  145. end;
  146. end;
  147. procedure TMainForm.Image32PaintStage(Sender: TObject; Buffer: TBitmap32;
  148. StageNum: Cardinal);
  149. const
  150. Colors: array [0..1] of TColor32 = ($FFFFFFFF, $FFB0B0B0);
  151. var
  152. W, I, J, Parity: Integer;
  153. Line1, Line2: TArrayOfColor32; // a buffer for a couple of scanlines
  154. begin
  155. with Image32.Buffer do
  156. if StageNum = 0 then
  157. begin
  158. W := Width;
  159. SetLength(Line1, W);
  160. SetLength(Line2, W);
  161. for I := 0 to W - 1 do
  162. begin
  163. Parity := I shr 3 and $1;
  164. Line1[I] := Colors[Parity];
  165. Line2[I] := Colors[1 - Parity];
  166. end;
  167. for J := 0 to Height - 1 do
  168. begin
  169. Parity := J shr 3 and $1;
  170. if Boolean(Parity) then
  171. MoveLongword(Line1[0], ScanLine[J]^, W)
  172. else
  173. MoveLongword(Line2[0], ScanLine[J]^, W);
  174. end;
  175. end
  176. else
  177. FrameRectS(BoundsRect , $FF000000);
  178. end;
  179. procedure TMainForm.GbrTwistChange(Sender: TObject);
  180. begin
  181. with Image32 do
  182. begin
  183. TwirlDistortion(Bitmap, Src, GbrTwist.Position);
  184. GbrTwist.Repaint;
  185. Repaint;
  186. end;
  187. end;
  188. end.