MainUnit.pas 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. unit MainUnit;
  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 ByteMaps Example
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Alex A. Denisov
  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. {$IFDEF FPC}LCLIntf, {$ENDIF} SysUtils, Classes, Graphics, Controls, Forms,
  37. Dialogs, ExtCtrls, StdCtrls, ComCtrls, Math, Clipbrd, ExtDlgs, ToolWin,
  38. ImgList, Menus, GR32, GR32_OrdinalMaps, GR32_RangeBars, GR32_Image,
  39. GR32_Layers, System.ImageList;
  40. type
  41. TMainForm = class(TForm)
  42. BtnCopy: TToolButton;
  43. BtnLinear: TToolButton;
  44. BtnNew: TToolButton;
  45. BtnOpen: TToolButton;
  46. BtnSave: TToolButton;
  47. {$IFDEF FPC}
  48. CoolBar: TToolBar;
  49. {$ELSE}
  50. CoolBar: TCoolBar;
  51. {$ENDIF}
  52. Image: TImgView32;
  53. ImageList: TImageList;
  54. LblPalette: TLabel;
  55. LblZoom: TLabel;
  56. MainMenu: TMainMenu;
  57. mnCopy: TMenuItem;
  58. mnEdit: TMenuItem;
  59. mnExit: TMenuItem;
  60. mnFile: TMenuItem;
  61. mnNew: TMenuItem;
  62. mnOpen: TMenuItem;
  63. mnSave: TMenuItem;
  64. N1: TMenuItem;
  65. OpenPictureDialog: TOpenPictureDialog;
  66. PaletteCombo: TComboBox;
  67. PnlMain: TPanel;
  68. PnlScaleBar: TPanel;
  69. PnlSepartator: TPanel;
  70. PnlGR32: TPanel;
  71. SavePictureDialog: TSavePictureDialog;
  72. ScaleBar: TGaugeBar;
  73. BtnEdit: TToolButton;
  74. BtnFile: TToolButton;
  75. ToolBar1: TToolBar;
  76. ToolBar2: TToolBar;
  77. TbrMain: TToolBar;
  78. BtnSeparator1: TToolButton;
  79. BtnSeparator2: TToolButton;
  80. procedure FormCreate(Sender: TObject);
  81. procedure FormDestroy(Sender: TObject);
  82. procedure CheckBox1Click(Sender: TObject);
  83. procedure CopyClick(Sender: TObject);
  84. procedure ImageMouseDown(Sender: TObject; Button: TMouseButton;
  85. Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
  86. procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer;
  87. Layer: TCustomLayer);
  88. procedure ImageMouseUp(Sender: TObject; Button: TMouseButton;
  89. Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
  90. procedure mnExitClick(Sender: TObject);
  91. procedure NewClick(Sender: TObject);
  92. procedure OpenClick(Sender: TObject);
  93. procedure PaletteComboChange(Sender: TObject);
  94. procedure SaveClick(Sender: TObject);
  95. procedure ScaleChange(Sender: TObject);
  96. public
  97. DataSet: TByteMap;
  98. PalGrayscale: TPalette32;
  99. PalGreens: TPalette32;
  100. PalReds: TPalette32;
  101. PalRainbow: TPalette32;
  102. OldMousePos: TPoint;
  103. MouseDragging: Boolean;
  104. procedure GenPalettes;
  105. procedure GenSampleData(W, H: Integer);
  106. procedure PaintData;
  107. end;
  108. var
  109. MainForm: TMainForm;
  110. implementation
  111. {$IFDEF FPC}
  112. {$R *.lfm}
  113. {$ELSE}
  114. {$R *.dfm}
  115. {$ENDIF}
  116. uses
  117. {$IFNDEF FPC}
  118. Windows,
  119. JPEG;
  120. {$ELSE}
  121. LazJPG;
  122. {$ENDIF}
  123. // TMainForm
  124. procedure TMainForm.FormCreate(Sender: TObject);
  125. begin
  126. PaletteCombo.ItemIndex := 0;
  127. GenPalettes;
  128. DataSet := TByteMap.Create;
  129. end;
  130. procedure TMainForm.FormDestroy(Sender: TObject);
  131. begin
  132. DataSet.Free;
  133. end;
  134. procedure TMainForm.GenPalettes;
  135. var
  136. Index: Integer;
  137. Scale: Single;
  138. begin
  139. for Index := 0 to 255 do
  140. begin
  141. Scale := Index / 255;
  142. PalGrayscale[Index] := HSLtoRGB(0, 0, Scale * 0.9 + 0.1);
  143. PalGreens[Index] := HSLtoRGB(Scale * 0.4, 0.5, Scale * 0.4 + 0.2);
  144. PalReds[Index] := HSLtoRGB(0.8 + Scale * 0.3, 0.7 + Scale * 0.3,
  145. Scale * 0.85 + 0.1);
  146. PalRainbow[Index] := HSLtoRGB(0.66 - Scale * 0.7, 1, 0.4 + 0.4 * Scale);
  147. end;
  148. end;
  149. function Clamp(FloatVal: Extended): Byte;
  150. begin
  151. if FloatVal <= 0 then
  152. Result := 0
  153. else if FloatVal >= 1 then
  154. Result := 255
  155. else
  156. Result := Round(FloatVal * 255);
  157. end;
  158. procedure TMainForm.GenSampleData(W, H: Integer);
  159. var
  160. X, Y: Integer;
  161. begin
  162. DataSet.SetSize(W, H);
  163. for Y := 0 to H - 1 do
  164. for X := 0 to W - 1 do
  165. begin
  166. // just some noise
  167. DataSet[X, Y] := Clamp(0.5 + 0.5 * Sin(X + Random(10)) * 0.01 + 0.5 *
  168. Cos(Y / 11) + 0.2 * Sin((X + Y) / 3));
  169. end;
  170. end;
  171. procedure TMainForm.PaintData;
  172. var
  173. P: PPalette32;
  174. begin
  175. case PaletteCombo.ItemIndex of
  176. 0:
  177. P := @PalGrayscale;
  178. 1:
  179. P := @PalGreens;
  180. 2:
  181. P := @PalReds;
  182. else
  183. P := @PalRainbow;
  184. end;
  185. DataSet.WriteTo(Image.Bitmap, P^);
  186. end;
  187. procedure TMainForm.PaletteComboChange(Sender: TObject);
  188. begin
  189. PaintData;
  190. end;
  191. procedure TMainForm.NewClick(Sender: TObject);
  192. begin
  193. GenSampleData(300, 220);
  194. PaintData;
  195. mnSave.Enabled := True;
  196. mnCopy.Enabled := True;
  197. BtnSave.Enabled := True;
  198. BtnCopy.Enabled := True;
  199. end;
  200. procedure TMainForm.ScaleChange(Sender: TObject);
  201. var
  202. NewScale: Single;
  203. begin
  204. NewScale := Power(10, ScaleBar.Position * 0.01);
  205. ScaleBar.Repaint; // update the scale bar before the image is repainted
  206. Image.Scale := NewScale;
  207. end;
  208. procedure TMainForm.CheckBox1Click(Sender: TObject);
  209. begin
  210. // Don't use aux. resampler setup, pass class names directly:
  211. if BtnLinear.Down then
  212. Image.Bitmap.ResamplerClassName := 'TLinearResampler'
  213. else
  214. Image.Bitmap.ResamplerClassName := 'TNearestResampler';
  215. end;
  216. procedure TMainForm.CopyClick(Sender: TObject);
  217. begin
  218. Clipboard.Assign(Image.Bitmap);
  219. end;
  220. procedure TMainForm.SaveClick(Sender: TObject);
  221. begin
  222. Application.ProcessMessages;
  223. with SavePictureDialog do
  224. if Execute then
  225. Image.Bitmap.SaveToFile(FileName);
  226. end;
  227. procedure TMainForm.ImageMouseDown(Sender: TObject; Button: TMouseButton;
  228. Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
  229. begin
  230. if Button = mbLeft then
  231. begin
  232. OldMousePos := Point(X, Y);
  233. MouseDragging := True;
  234. Image.Cursor := crSizeAll;
  235. end
  236. else
  237. ReleaseCapture;
  238. end;
  239. procedure TMainForm.ImageMouseMove(Sender: TObject; Shift: TShiftState;
  240. X, Y: Integer; Layer: TCustomLayer);
  241. begin
  242. if MouseDragging then
  243. begin
  244. Image.Scroll(OldMousePos.X - X, OldMousePos.Y - Y);
  245. OldMousePos := Point(X, Y);
  246. Image.Update;
  247. end;
  248. end;
  249. procedure TMainForm.ImageMouseUp(Sender: TObject; Button: TMouseButton;
  250. Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
  251. begin
  252. if Button = mbLeft then
  253. begin
  254. MouseDragging := False;
  255. Image.Cursor := crDefault;
  256. end;
  257. end;
  258. procedure TMainForm.mnExitClick(Sender: TObject);
  259. begin
  260. Close;
  261. end;
  262. procedure TMainForm.OpenClick(Sender: TObject);
  263. var
  264. B: TBitmap32;
  265. begin
  266. Application.ProcessMessages;
  267. with OpenPictureDialog do
  268. if Execute then
  269. begin
  270. // Create a temporary bitmap
  271. B := TBitmap32.Create;
  272. try
  273. B.LoadFromFile(FileName);
  274. // Convert it to grayscale values and store it into the byte map
  275. DataSet.ReadFrom(B, ctWeightedRGB);
  276. finally
  277. B.Free;
  278. end;
  279. PaintData;
  280. mnSave.Enabled := True;
  281. mnCopy.Enabled := True;
  282. BtnSave.Enabled := True;
  283. BtnCopy.Enabled := True;
  284. end;
  285. end;
  286. end.