MainUnit.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. unit MainUnit;
  2. interface
  3. uses
  4. {$IFNDEF FPC} Windows, {$ELSE} LCLIntf, LCLType, {$ENDIF}
  5. SysUtils, Classes, Graphics, Controls, Forms, Menus, Dialogs, ComCtrls,
  6. ExtCtrls, StdCtrls, Math, GR32, GR32_Image, GR32_Layers, GR32_System;
  7. type
  8. TFrmBlurs = class(TForm)
  9. MnuBlurType: TMenuItem;
  10. CbxBidirectional: TCheckBox;
  11. MnuFile: TMenuItem;
  12. ImgViewPage1: TImgView32;
  13. ImgViewPage2: TImgView32;
  14. ImgViewPage3: TImgView32;
  15. LblBlurAngle: TLabel;
  16. LblBlurRadius: TLabel;
  17. MainMenu: TMainMenu;
  18. MnuExit: TMenuItem;
  19. MnuFastGaussian: TMenuItem;
  20. MnuGaussianType: TMenuItem;
  21. MnuMotion: TMenuItem;
  22. MnuNone: TMenuItem;
  23. N1: TMenuItem;
  24. MnuOpen: TMenuItem;
  25. OpenDialog: TOpenDialog;
  26. PageControl: TPageControl;
  27. PnlControl: TPanel;
  28. RgpBlurType: TRadioGroup;
  29. SbrMain: TStatusBar;
  30. TabSheet1: TTabSheet;
  31. TabSheet2: TTabSheet;
  32. TabSheet3: TTabSheet;
  33. TbrBlurAngle: TTrackBar;
  34. TbrBlurRadius: TTrackBar;
  35. CheckBoxCorrectGamma: TCheckBox;
  36. procedure FormCreate(Sender: TObject);
  37. procedure FormDestroy(Sender: TObject);
  38. procedure MnuExitClick(Sender: TObject);
  39. procedure MnuGaussianTypeClick(Sender: TObject);
  40. procedure MnuOpenClick(Sender: TObject);
  41. procedure PageControlChange(Sender: TObject);
  42. procedure RgpBlurTypeClick(Sender: TObject);
  43. procedure TbrBlurAngleChange(Sender: TObject);
  44. procedure TbrBlurRadiusChange(Sender: TObject);
  45. private
  46. FPerfTimer: TPerfTimer;
  47. FDuration: string;
  48. FReDrawFlag: Boolean;
  49. FStoneWeedImage: TBitmap32;
  50. FIcelandImage: TBitmap32;
  51. FRandBoxImage: TBitmap32;
  52. FBmpLayer: TBitmapLayer;
  53. procedure ReDraw;
  54. end;
  55. var
  56. FrmBlurs: TFrmBlurs;
  57. implementation
  58. uses
  59. {$IFNDEF FPC} JPEG, {$ELSE} LazJPG, {$ENDIF}
  60. GR32_Polygons, GR32_VectorUtils, GR32_Blurs, GR32_Resamplers;
  61. {$IFDEF FPC}
  62. {$R *.lfm}
  63. {$ELSE}
  64. {$R *.dfm}
  65. {$ENDIF}
  66. { Miscellaneous functions }
  67. procedure DrawFramedBox(Bmp32: TBitmap32; const Rec: TRect;
  68. Color1, Color2: TColor32; LineWidth: TFloat);
  69. var
  70. Pts: TArrayOfFloatPoint;
  71. begin
  72. if LineWidth < 1 then LineWidth := 1;
  73. SetLength(Pts, 6);
  74. with Rec do
  75. begin
  76. Pts[0] := FloatPoint(Left, Bottom);
  77. Pts[1] := FloatPoint(Left, Top);
  78. Pts[2] := FloatPoint(Right, Top);
  79. Pts[3] := FloatPoint(Right - LineWidth, Top + LineWidth);
  80. Pts[4] := FloatPoint(Left + LineWidth, Top + LineWidth);
  81. Pts[5] := FloatPoint(Left + LineWidth, Bottom - LineWidth);
  82. PolygonFS(Bmp32, Pts, Color1);
  83. Pts[1] := FloatPoint(Right, Bottom);
  84. Pts[2] := FloatPoint(Right, Top);
  85. Pts[3] := FloatPoint(Right - LineWidth, Top + LineWidth);
  86. Pts[4] := FloatPoint(Right - LineWidth, Bottom - LineWidth);
  87. Pts[5] := FloatPoint(Left + LineWidth, Bottom - LineWidth);
  88. PolygonFS(Bmp32, Pts, Color2);
  89. end;
  90. end;
  91. procedure LoadJPGResource(const ResName: string; Bmp32: TBitmap32);
  92. var
  93. ResStream: TResourceStream;
  94. JPEG: TJPEGImage;
  95. begin
  96. JPEG := TJPEGImage.Create;
  97. ResStream := TResourceStream.Create(hInstance, ResName, RT_RCDATA);
  98. try
  99. JPEG.LoadFromStream(ResStream);
  100. Bmp32.Assign(JPEG);
  101. finally
  102. ResStream.Free;
  103. JPEG.Free;
  104. end;
  105. end;
  106. { TFrmBlurs }
  107. procedure TFrmBlurs.FormCreate(Sender: TObject);
  108. var
  109. I, J: Integer;
  110. const
  111. Colors: array [0 .. 21] of TColor32 = (clAliceBlue32, clAquamarine32,
  112. clAzure32, clBeige32, clBlueViolet32, clCadetblue32, clChocolate32,
  113. clCoral32, clCornFlowerBlue32, clCornSilk32, clCrimson32,
  114. clDarkBlue32, clDarkCyan32, clDarkGoldenRod32, clDarkGreen32,
  115. clDarkMagenta32, clDarkOrange32, clDarkOrchid32, clDarkRed32,
  116. clDarkSalmon32, clDarkSeaGreen32, clDarkSlateBlue32);
  117. begin
  118. FStoneWeedImage := TBitmap32.create;
  119. FIcelandImage := TBitmap32.create;
  120. // Just use FStoneWeedImage momentarily to load a 600*400 image of ICELAND ...
  121. LoadJPGResource('ICELAND', FStoneWeedImage);
  122. FIcelandImage.SetSize(600, 400);
  123. FStoneWeedImage.DrawTo(FIcelandImage, FIcelandImage.BoundsRect,
  124. FStoneWeedImage.BoundsRect);
  125. // Now load the real STONEWEED image ...
  126. LoadJPGResource('STONEWEED', FStoneWeedImage);
  127. FPerfTimer := TPerfTimer.Create;
  128. Randomize;
  129. FRandBoxImage := TBitmap32.create;
  130. //generate an image of full of random boxes ...
  131. FRandBoxImage.SetSize(192, 272);
  132. for I := 0 to 11 do
  133. for J := 0 to 16 do
  134. FRandBoxImage.FillRectS(I * 16, J * 16, 300 + (I + 1) * 16,
  135. 40 + (J +1) * 16, SetAlpha(Colors[Random(22)], 128));
  136. FBmpLayer := TBitmapLayer(ImgViewPage3.Layers.Add(TBitmapLayer));
  137. FBmpLayer.Bitmap.DrawMode := dmBlend;
  138. ReDraw;
  139. end;
  140. procedure TFrmBlurs.FormDestroy(Sender: TObject);
  141. begin
  142. FPerfTimer.Free;
  143. FStoneWeedImage.Free;
  144. FIcelandImage.Free;
  145. FRandBoxImage.Free;
  146. end;
  147. procedure TFrmBlurs.ReDraw;
  148. var
  149. Radius: Integer;
  150. Rec, Rec2: TRect;
  151. Pts, Pts2: TArrayOfFloatPoint;
  152. WithGamma: Boolean;
  153. begin
  154. if FReDrawFlag then
  155. Exit;
  156. FReDrawFlag := True;
  157. Radius := TbrBlurRadius.Position;
  158. Screen.Cursor := crHourGlass;
  159. WithGamma := CheckBoxCorrectGamma.Checked;
  160. case PageControl.ActivePageIndex of
  161. 0:
  162. begin
  163. ImgViewPage1.BeginUpdate;
  164. ImgViewPage1.Bitmap.Assign(FIcelandImage);
  165. FPerfTimer.Start;
  166. case RgpBlurType.ItemIndex of
  167. 1:
  168. GaussianBlurSimple[WithGamma](ImgViewPage1.Bitmap, Radius);
  169. 2:
  170. FastBlurSimple[WithGamma](ImgViewPage1.Bitmap, Radius);
  171. 3:
  172. if WithGamma then
  173. MotionBlurGamma(ImgViewPage1.Bitmap, Radius,
  174. TbrBlurAngle.Position, CbxBidirectional.Checked)
  175. else
  176. MotionBlur(ImgViewPage1.Bitmap, Radius,
  177. TbrBlurAngle.Position, CbxBidirectional.Checked)
  178. end;
  179. FDuration := FPerfTimer.ReadMilliseconds;
  180. ImgViewPage1.EndUpdate;
  181. ImgViewPage1.Repaint;
  182. Application.ProcessMessages;
  183. end;
  184. 1:
  185. begin
  186. ImgViewPage2.BeginUpdate;
  187. ImgViewPage2.Bitmap.Assign(FStoneWeedImage);
  188. Pts := Star(130, 150, 90, 5, -0.5 * Pi);
  189. Pts2 := Ellipse(350, 250, 100, 60);
  190. FPerfTimer.Start;
  191. case RgpBlurType.ItemIndex of
  192. 1:
  193. begin
  194. GaussianBlurRegion[WithGamma](ImgViewPage2.Bitmap, Radius, Pts);
  195. GaussianBlurRegion[WithGamma](ImgViewPage2.Bitmap, Radius, Pts2);
  196. end;
  197. 2:
  198. begin
  199. FastBlurRegion[WithGamma](ImgViewPage2.Bitmap, Radius, Pts);
  200. FastBlurRegion[WithGamma](ImgViewPage2.Bitmap, Radius, Pts2);
  201. end;
  202. 3:
  203. if WithGamma then
  204. begin
  205. MotionBlurGamma(ImgViewPage2.Bitmap, Radius, TbrBlurAngle.Position,
  206. Pts, CbxBidirectional.Checked);
  207. MotionBlurGamma(ImgViewPage2.Bitmap, Radius, TbrBlurAngle.Position,
  208. Pts2, CbxBidirectional.Checked);
  209. end
  210. else
  211. begin
  212. MotionBlur(ImgViewPage2.Bitmap, Radius, TbrBlurAngle.Position,
  213. Pts, CbxBidirectional.Checked);
  214. MotionBlur(ImgViewPage2.Bitmap, Radius, TbrBlurAngle.Position,
  215. Pts2, CbxBidirectional.Checked);
  216. end;
  217. end;
  218. FDuration := FPerfTimer.ReadMilliseconds;
  219. Application.ProcessMessages;
  220. PolylineFS(ImgViewPage2.Bitmap, Pts, clBlack32, True, 2.5);
  221. PolylineFS(ImgViewPage2.Bitmap, Pts2, clBlack32, True, 2.5);
  222. ImgViewPage2.EndUpdate;
  223. ImgViewPage2.Repaint;
  224. end;
  225. 2:
  226. begin
  227. ImgViewPage3.BeginUpdate;
  228. ImgViewPage3.SetupBitmap(True, Color32(clBtnFace));
  229. FBmpLayer.Bitmap.Clear(0);
  230. with ImgViewPage3.GetBitmapRect do
  231. begin
  232. FBmpLayer.Location := FloatRect(Left, Top, Right, Bottom);
  233. FBmpLayer.Bitmap.SetSize(Right - Left, Bottom - Top)
  234. end;
  235. FBmpLayer.Bitmap.Draw(300, 40, FRandBoxImage);
  236. Rec := Rect(40, 40, 240, 120);
  237. DrawFramedBox(ImgViewPage3.Bitmap, Rec, clWhite32, clGray32, Radius div 2);
  238. Rec2 := Rect(40, 160, 240, 320);
  239. with Rec2 do
  240. FBmpLayer.Bitmap.FillRect(Left, Top, Right, Bottom, clRed32);
  241. InflateRect(Rec2, 20, 20);
  242. Pts := Ellipse(395, 175, 60, 100);
  243. FPerfTimer.Start;
  244. case RgpBlurType.ItemIndex of
  245. 1:
  246. begin
  247. GaussianBlurBounds[WithGamma](ImgViewPage3.Bitmap, Radius, Rec);
  248. GaussianBlurBounds[WithGamma](FBmpLayer.Bitmap, Radius, Rec2);
  249. GaussianBlurRegion[WithGamma](FBmpLayer.Bitmap, Radius, Pts);
  250. end;
  251. 2:
  252. begin
  253. FastBlurBounds[WithGamma](ImgViewPage3.Bitmap, Radius, Rec);
  254. FastBlurBounds[WithGamma](FBmpLayer.Bitmap, Radius, Rec2);
  255. FastBlurRegion[WithGamma](FBmpLayer.Bitmap, Radius, Pts);
  256. end;
  257. 3:
  258. if WithGamma then
  259. begin
  260. MotionBlurGamma(ImgViewPage3.Bitmap, Radius,
  261. TbrBlurAngle.Position, Rec, CbxBidirectional.Checked);
  262. MotionBlurGamma(FBmpLayer.Bitmap, Radius,
  263. TbrBlurAngle.Position, Rec2, CbxBidirectional.Checked);
  264. MotionBlurGamma(FBmpLayer.Bitmap, Radius,
  265. TbrBlurAngle.Position, Pts, CbxBidirectional.Checked);
  266. end
  267. else
  268. begin
  269. MotionBlur(ImgViewPage3.Bitmap, Radius,
  270. TbrBlurAngle.Position, Rec, CbxBidirectional.Checked);
  271. MotionBlur(FBmpLayer.Bitmap, Radius,
  272. TbrBlurAngle.Position, Rec2, CbxBidirectional.Checked);
  273. MotionBlur(FBmpLayer.Bitmap, Radius,
  274. TbrBlurAngle.Position, Pts, CbxBidirectional.Checked);
  275. end;
  276. end;
  277. FDuration := FPerfTimer.ReadMilliseconds;
  278. Application.ProcessMessages;
  279. PolylineFS(FBmpLayer.Bitmap, Pts, clBlack32, True, 2.5);
  280. with Rec2 do
  281. PolylineFS(
  282. FBmpLayer.Bitmap,
  283. BuildPolygonF([
  284. Left, Top, Right, Top, Right, Bottom, Left, Bottom]),
  285. clBlack32,
  286. True,
  287. 0.5);
  288. ImgViewPage3.EndUpdate;
  289. ImgViewPage3.Repaint;
  290. end;
  291. end;
  292. SbrMain.SimpleText := Format(' Blur drawing time: %s ms', [FDuration]);
  293. Screen.Cursor := crDefault;
  294. FReDrawFlag := False;
  295. end;
  296. procedure TFrmBlurs.MnuExitClick(Sender: TObject);
  297. begin
  298. Close;
  299. end;
  300. procedure TFrmBlurs.RgpBlurTypeClick(Sender: TObject);
  301. begin
  302. MnuNone.Checked := RgpBlurType.ItemIndex = 0;
  303. MnuGaussianType.Checked := RgpBlurType.ItemIndex = 1;
  304. MnuFastGaussian.Checked := RgpBlurType.ItemIndex = 2;
  305. MnuMotion.Checked := RgpBlurType.ItemIndex = 3;
  306. LblBlurAngle.Enabled := MnuMotion.Checked;
  307. TbrBlurAngle.Enabled := MnuMotion.Checked;
  308. CbxBidirectional.Enabled := MnuMotion.Checked;
  309. ReDraw;
  310. end;
  311. procedure TFrmBlurs.TbrBlurRadiusChange(Sender: TObject);
  312. begin
  313. LblBlurRadius.Caption :=
  314. Format('Blur &Radius (%d)', [TbrBlurRadius.Position]);
  315. ReDraw;
  316. end;
  317. procedure TFrmBlurs.TbrBlurAngleChange(Sender: TObject);
  318. begin
  319. LblBlurAngle.Caption :=
  320. Format('Blur &Angle (%d)', [TbrBlurAngle.Position]);
  321. ReDraw;
  322. end;
  323. procedure TFrmBlurs.MnuGaussianTypeClick(Sender: TObject);
  324. begin
  325. if Sender = MnuNone then
  326. RgpBlurType.ItemIndex := 0
  327. else if Sender = MnuGaussianType then
  328. RgpBlurType.ItemIndex := 1
  329. else if Sender = MnuFastGaussian then
  330. RgpBlurType.ItemIndex := 2
  331. else
  332. RgpBlurType.ItemIndex := 3;
  333. end;
  334. procedure TFrmBlurs.MnuOpenClick(Sender: TObject);
  335. var
  336. Extension: String;
  337. begin
  338. if OpenDialog.Execute then
  339. begin
  340. Extension := Lowercase(ExtractFileExt(OpenDialog.FileName));
  341. FIcelandImage.LoadFromFile(OpenDialog.FileName);
  342. PageControl.ActivePageIndex := 0;
  343. ReDraw;
  344. end;
  345. end;
  346. procedure TFrmBlurs.PageControlChange(Sender: TObject);
  347. begin
  348. ReDraw;
  349. end;
  350. end.