MainUnit.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. {$include GR32.inc}
  35. uses
  36. {$IFDEF FPC}LCLIntf, {$ENDIF} SysUtils, Classes, Graphics, Controls, Forms,
  37. Dialogs, ExtCtrls, StdCtrls, ComCtrls, Clipbrd, ExtDlgs,
  38. Menus,
  39. GR32,
  40. GR32_OrdinalMaps,
  41. GR32_RangeBars,
  42. GR32_Image,
  43. GR32_Layers;
  44. type
  45. TMainForm = class(TForm)
  46. Image: TImgView32;
  47. MainMenu: TMainMenu;
  48. MenuItemCopy: TMenuItem;
  49. mnEdit: TMenuItem;
  50. mnExit: TMenuItem;
  51. mnFile: TMenuItem;
  52. mnNew: TMenuItem;
  53. mnOpen: TMenuItem;
  54. MenuItemSave: TMenuItem;
  55. N1: TMenuItem;
  56. OpenPictureDialog: TOpenPictureDialog;
  57. PnlMain: TPanel;
  58. PnlSepartator: TPanel;
  59. SavePictureDialog: TSavePictureDialog;
  60. Panel1: TPanel;
  61. ScaleBar: TGaugeBar;
  62. Label1: TLabel;
  63. PaletteCombo: TComboBox;
  64. Label2: TLabel;
  65. View1: TMenuItem;
  66. MenuItemLinear: TMenuItem;
  67. procedure FormCreate(Sender: TObject);
  68. procedure FormDestroy(Sender: TObject);
  69. procedure CopyClick(Sender: TObject);
  70. procedure mnExitClick(Sender: TObject);
  71. procedure NewClick(Sender: TObject);
  72. procedure OpenClick(Sender: TObject);
  73. procedure PaletteComboChange(Sender: TObject);
  74. procedure SaveClick(Sender: TObject);
  75. procedure ScaleChange(Sender: TObject);
  76. procedure MenuItemLinearClick(Sender: TObject);
  77. procedure ImageScaleChange(Sender: TObject);
  78. public
  79. DataSet: TByteMap;
  80. PalGrayscale: TPalette32;
  81. PalGreens: TPalette32;
  82. PalReds: TPalette32;
  83. PalRainbow: TPalette32;
  84. procedure GenPalettes;
  85. procedure GenSampleData(W, H: Integer);
  86. procedure PaintData;
  87. end;
  88. var
  89. MainForm: TMainForm;
  90. implementation
  91. {$R *.dfm}
  92. uses
  93. Types,
  94. Math;
  95. { TMainForm }
  96. procedure TMainForm.FormCreate(Sender: TObject);
  97. begin
  98. PaletteCombo.ItemIndex := 0;
  99. GenPalettes;
  100. DataSet := TByteMap.Create;
  101. end;
  102. procedure TMainForm.FormDestroy(Sender: TObject);
  103. begin
  104. DataSet.Free;
  105. end;
  106. procedure TMainForm.GenPalettes;
  107. var
  108. Index: Integer;
  109. Scale: Single;
  110. begin
  111. for Index := 0 to 255 do
  112. begin
  113. Scale := Index / 255;
  114. PalGrayscale[Index] := HSLtoRGB(0, 0, Scale * 0.9 + 0.1);
  115. PalGreens[Index] := HSLtoRGB(Scale * 0.4, 0.5, Scale * 0.4 + 0.2);
  116. PalReds[Index] := HSLtoRGB(0.8 + Scale * 0.3 , 0.7 + Scale * 0.3, Scale * 0.85 + 0.1);
  117. PalRainbow[Index] := HSLtoRGB(0.66 - Scale * 0.7, 1, 0.4 + 0.4 * Scale);
  118. end;
  119. end;
  120. procedure TMainForm.GenSampleData(W, H: Integer);
  121. var
  122. X, Y: Integer;
  123. function Clamp(FloatVal: Extended): Byte;
  124. begin
  125. if FloatVal <= 0 then Result := 0
  126. else if FloatVal >= 1 then Result := 255
  127. else Result := Round(FloatVal * 255);
  128. end;
  129. begin
  130. DataSet.SetSize(W, H);
  131. for Y := 0 to H - 1 do
  132. for X := 0 to W - 1 do
  133. begin
  134. // just some noise
  135. DataSet[X, Y] := Clamp(0.5 +
  136. 0.5 * Sin(X + Random(10)) * 0.01 +
  137. 0.5 * Cos(Y / 11) +
  138. 0.2 * Sin((X + Y) / 3));
  139. end;
  140. end;
  141. procedure TMainForm.ImageScaleChange(Sender: TObject);
  142. begin
  143. ScaleBar.Position := Round(Log10(Image.Scale) * 100);
  144. end;
  145. procedure TMainForm.PaintData;
  146. var
  147. P: PPalette32;
  148. begin
  149. case PaletteCombo.ItemIndex of
  150. 0: P := @PalGrayscale;
  151. 1: P := @PalGreens;
  152. 2: P := @PalReds;
  153. else
  154. P := @PalRainbow;
  155. end;
  156. DataSet.WriteTo(Image.Bitmap, P^);
  157. end;
  158. procedure TMainForm.PaletteComboChange(Sender: TObject);
  159. begin
  160. PaintData;
  161. end;
  162. procedure TMainForm.NewClick(Sender: TObject);
  163. begin
  164. GenSampleData(300, 220);
  165. PaintData;
  166. MenuItemSave.Enabled := True;
  167. MenuItemCopy.Enabled := True;
  168. end;
  169. procedure TMainForm.ScaleChange(Sender: TObject);
  170. var
  171. NewScale: Single;
  172. begin
  173. NewScale := Power(10, ScaleBar.Position * 0.01);
  174. ScaleBar.Repaint; // update the scale bar before the image is repainted
  175. Image.Scale := NewScale;
  176. end;
  177. procedure TMainForm.CopyClick(Sender: TObject);
  178. begin
  179. Clipboard.Assign(Image.Bitmap);
  180. end;
  181. procedure TMainForm.SaveClick(Sender: TObject);
  182. begin
  183. with SavePictureDialog do
  184. if Execute then Image.Bitmap.SaveToFile(FileName);
  185. end;
  186. procedure TMainForm.MenuItemLinearClick(Sender: TObject);
  187. begin
  188. // Don't use aux. resampler setup, pass class names directly:
  189. if MenuItemLinear.Checked then
  190. Image.Bitmap.ResamplerClassName := 'TLinearResampler'
  191. else
  192. Image.Bitmap.ResamplerClassName := 'TNearestResampler';
  193. end;
  194. procedure TMainForm.mnExitClick(Sender: TObject);
  195. begin
  196. Close;
  197. end;
  198. procedure TMainForm.OpenClick(Sender: TObject);
  199. var
  200. B: TBitmap32;
  201. begin
  202. Application.ProcessMessages;
  203. with OpenPictureDialog do
  204. if Execute then
  205. begin
  206. { Create a temporary bitmap }
  207. B := TBitmap32.Create;
  208. try
  209. B.LoadFromFile(FileName);
  210. { Convert it to grayscale values and store it into the byte map }
  211. DataSet.ReadFrom(B, ctWeightedRGB);
  212. finally
  213. B.Free;
  214. end;
  215. PaintData;
  216. MenuItemSave.Enabled := True;
  217. MenuItemCopy.Enabled := True;
  218. end;
  219. end;
  220. end.