mainunit.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. {
  2. Vampyre Imaging Library Demo
  3. LCL Imager (ObjectPascal, high level/component sets/canvas, Win32/Linux)
  4. tested in Lazarus 0.9.18
  5. written by Marek Mauder
  6. Simple image manipulator program which shows usage of Imaging VCL/CLX/LCL
  7. classes (TImagingGraphic and its descendants) to display images on form.
  8. It also uses high level image classes and some low level functions.
  9. Demo uses TMultiImage class to store images (loaded from one file - MNG, DDS)
  10. which can be modified by user. After each modification image
  11. is assigned to TImagingBitmap class which provides visualization
  12. on the app form (using standard TImage component). Demo also uses new
  13. TImagingCanvas class to do some effects.
  14. In File menu you can open new image and save the current one. Items in
  15. View menu provide information about the current image and controls
  16. how it is displayed. You can also select next and previous subimage if loaded file
  17. contains more than one image. Format menu allows you to convert image
  18. to different image data formats supported by Imaging. Manipulate
  19. menu allows you to enlarge/shrink/flip/mirror/swap channels/other
  20. of the current image. Effects menu allows you to apply various effects to the
  21. image (provided by TImagingCanvas).
  22. }
  23. unit MainUnit;
  24. {$mode objfpc}{$H+}
  25. interface
  26. uses
  27. Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  28. Menus, ExtCtrls, ExtDlgs, DemoUtils, AboutUnit, ActnList,
  29. ImagingTypes,
  30. Imaging,
  31. ImagingClasses,
  32. ImagingComponents,
  33. ImagingCanvases,
  34. ImagingUtility;
  35. type
  36. { TMainForm }
  37. TMainForm = class(TForm)
  38. ActViewInfo: TAction;
  39. ActViewFitToWindow: TAction;
  40. ActViewRealSize: TAction;
  41. ActionList1: TActionList;
  42. Image: TImage;
  43. MainMenu: TMainMenu;
  44. MenuItem1: TMenuItem;
  45. MenuItem10: TMenuItem;
  46. MenuItem11: TMenuItem;
  47. MenuItem12: TMenuItem;
  48. MenuItem13: TMenuItem;
  49. MenuItem14: TMenuItem;
  50. MenuItem15: TMenuItem;
  51. MenuItem16: TMenuItem;
  52. MenuItem17: TMenuItem;
  53. FormatItem: TMenuItem;
  54. MenuItem18: TMenuItem;
  55. MenuItem19: TMenuItem;
  56. MenuItem2: TMenuItem;
  57. MenuItem20: TMenuItem;
  58. MenuItem21: TMenuItem;
  59. MenuItem22: TMenuItem;
  60. MenuItem23: TMenuItem;
  61. MenuItem24: TMenuItem;
  62. MenuItem25: TMenuItem;
  63. MenuItem26: TMenuItem;
  64. MenuItem27: TMenuItem;
  65. MenuItem28: TMenuItem;
  66. MenuItem29: TMenuItem;
  67. MenuItem3: TMenuItem;
  68. MenuItem30: TMenuItem;
  69. MenuItem31: TMenuItem;
  70. MenuItem32: TMenuItem;
  71. MenuItem33: TMenuItem;
  72. MenuItem36: TMenuItem;
  73. MenuItem37: TMenuItem;
  74. MenuItem38: TMenuItem;
  75. MenuItem39: TMenuItem;
  76. MenuItem40: TMenuItem;
  77. MenuItem41: TMenuItem;
  78. MenuItem42: TMenuItem;
  79. MenuItem43: TMenuItem;
  80. MenuItem44: TMenuItem;
  81. MenuItem46: TMenuItem;
  82. MenuItemActSubImage: TMenuItem;
  83. MenuItem34: TMenuItem;
  84. MenuItem35: TMenuItem;
  85. MenuItem4: TMenuItem;
  86. MenuItem5: TMenuItem;
  87. MenuItem6: TMenuItem;
  88. MenuItem7: TMenuItem;
  89. MenuItem8: TMenuItem;
  90. MenuItem9: TMenuItem;
  91. OpenD: TOpenPictureDialog;
  92. SaveD: TSavePictureDialog;
  93. procedure ActViewFitToWindowExecute(Sender: TObject);
  94. procedure ActViewInfoExecute(Sender: TObject);
  95. procedure ActViewRealSizeExecute(Sender: TObject);
  96. procedure FormCreate(Sender: TObject);
  97. procedure FormDestroy(Sender: TObject);
  98. procedure ImageClick(Sender: TObject);
  99. procedure MenuItem10Click(Sender: TObject);
  100. procedure MenuItem12Click(Sender: TObject);
  101. procedure MenuItem13Click(Sender: TObject);
  102. procedure MenuItem14Click(Sender: TObject);
  103. procedure MenuItem15Click(Sender: TObject);
  104. procedure MenuItem18Click(Sender: TObject);
  105. procedure MenuItem19Click(Sender: TObject);
  106. procedure MenuItem20Click(Sender: TObject);
  107. procedure MenuItem23Click(Sender: TObject);
  108. procedure MenuItem24Click(Sender: TObject);
  109. procedure MenuItem26Click(Sender: TObject);
  110. procedure MenuItem27Click(Sender: TObject);
  111. procedure MenuItem28Click(Sender: TObject);
  112. procedure MenuItem29Click(Sender: TObject);
  113. procedure MenuItem2Click(Sender: TObject);
  114. procedure MenuItem30Click(Sender: TObject);
  115. procedure MenuItem31Click(Sender: TObject);
  116. procedure MenuItem33Click(Sender: TObject);
  117. procedure MenuItem34Click(Sender: TObject);
  118. procedure MenuItem35Click(Sender: TObject);
  119. procedure MenuItem37Click(Sender: TObject);
  120. procedure MenuItem38Click(Sender: TObject);
  121. procedure MenuItem39Click(Sender: TObject);
  122. procedure MenuItem3Click(Sender: TObject);
  123. procedure MenuItem40Click(Sender: TObject);
  124. procedure MenuItem41Click(Sender: TObject);
  125. procedure MenuItem42Click(Sender: TObject);
  126. procedure MenuItem43Click(Sender: TObject);
  127. procedure MenuItem44Click(Sender: TObject);
  128. procedure MenuItem46Click(Sender: TObject);
  129. procedure MenuItem4Click(Sender: TObject);
  130. procedure MenuItem5Click(Sender: TObject);
  131. procedure MenuItem7Click(Sender: TObject);
  132. procedure FormatChangeClick(Sender: TObject);
  133. private
  134. FBitmap: TImagingBitmap;
  135. FImage: TMultiImage;
  136. FImageCanvas: TImagingCanvas;
  137. FFileName: string;
  138. procedure OpenFile(const FileName: string);
  139. procedure SelectSubimage(Index: LongInt);
  140. procedure UpdateView;
  141. function CheckCanvasFormat: Boolean;
  142. public
  143. end;
  144. const
  145. SWindowTitle = 'LCL Imager - Vampyre Imaging Library %s Demo';
  146. var
  147. MainForm: TMainForm;
  148. implementation
  149. { TMainForm }
  150. procedure TMainForm.MenuItem10Click(Sender: TObject);
  151. begin
  152. AboutForm.ShowModal;
  153. end;
  154. procedure TMainForm.MenuItem12Click(Sender: TObject);
  155. begin
  156. SwapChannels(FImage.ImageDataPointer^, ChannelRed, ChannelBlue);
  157. UpdateView;
  158. end;
  159. procedure TMainForm.MenuItem13Click(Sender: TObject);
  160. begin
  161. SwapChannels(FImage.ImageDataPointer^, ChannelRed, ChannelGreen);
  162. UpdateView;
  163. end;
  164. procedure TMainForm.MenuItem14Click(Sender: TObject);
  165. begin
  166. SwapChannels(FImage.ImageDataPointer^, ChannelGreen, ChannelBlue);
  167. UpdateView;
  168. end;
  169. procedure TMainForm.MenuItem15Click(Sender: TObject);
  170. begin
  171. ReduceColors(FImage.ImageDataPointer^, 1024);
  172. UpdateView;
  173. end;
  174. procedure TMainForm.MenuItem18Click(Sender: TObject);
  175. begin
  176. ReduceColors(FImage.ImageDataPointer^, 256);
  177. UpdateView;
  178. end;
  179. procedure TMainForm.MenuItem19Click(Sender: TObject);
  180. begin
  181. ReduceColors(FImage.ImageDataPointer^, 64);
  182. UpdateView;
  183. end;
  184. procedure TMainForm.MenuItem20Click(Sender: TObject);
  185. begin
  186. ReduceColors(FImage.ImageDataPointer^, 16);
  187. UpdateView;
  188. end;
  189. procedure TMainForm.MenuItem23Click(Sender: TObject);
  190. begin
  191. FImage.Rotate(-90);
  192. UpdateView;
  193. end;
  194. procedure TMainForm.MenuItem24Click(Sender: TObject);
  195. begin
  196. FImage.Rotate(90);
  197. UpdateView;
  198. end;
  199. procedure TMainForm.MenuItem26Click(Sender: TObject);
  200. begin
  201. FImage.Resize(FImage.Width div 2, FImage.Height div 2, rfNearest);
  202. UpdateView;
  203. end;
  204. procedure TMainForm.MenuItem27Click(Sender: TObject);
  205. begin
  206. FImage.Resize(FImage.Width div 2, FImage.Height div 2, rfBilinear);
  207. UpdateView;
  208. end;
  209. procedure TMainForm.MenuItem28Click(Sender: TObject);
  210. begin
  211. FImage.Resize(FImage.Width div 2, FImage.Height div 2, rfBicubic);
  212. UpdateView;
  213. end;
  214. procedure TMainForm.MenuItem29Click(Sender: TObject);
  215. begin
  216. FImage.Resize(FImage.Width * 2, FImage.Height * 2, rfNearest);
  217. UpdateView;
  218. end;
  219. procedure TMainForm.MenuItem2Click(Sender: TObject);
  220. begin
  221. FImage.Flip;;
  222. UpdateView;
  223. end;
  224. procedure TMainForm.MenuItem30Click(Sender: TObject);
  225. begin
  226. FImage.Resize(FImage.Width * 2, FImage.Height * 2, rfBilinear);
  227. UpdateView;
  228. end;
  229. procedure TMainForm.MenuItem31Click(Sender: TObject);
  230. begin
  231. FImage.Resize(FImage.Width * 2, FImage.Height * 2, rfBicubic);
  232. UpdateView;
  233. end;
  234. procedure TMainForm.MenuItem33Click(Sender: TObject);
  235. begin
  236. ReduceColors(FImage.ImageDataPointer^, 2);
  237. UpdateView;
  238. end;
  239. procedure TMainForm.MenuItem34Click(Sender: TObject);
  240. begin
  241. SelectSubimage(FImage.ActiveImage + 1);
  242. end;
  243. procedure TMainForm.MenuItem35Click(Sender: TObject);
  244. begin
  245. SelectSubimage(FImage.ActiveImage - 1);
  246. end;
  247. function TMainForm.CheckCanvasFormat: Boolean;
  248. begin
  249. Result := FImage.Format in FImageCanvas.GetSupportedFormats;
  250. if not Result then
  251. MessageDlg('Image is in format that is not supported by TImagingCanvas.', mtError, [mbOK], 0);
  252. end;
  253. procedure TMainForm.MenuItem37Click(Sender: TObject);
  254. begin
  255. if CheckCanvasFormat then
  256. begin
  257. FImageCanvas.CreateForImage(FImage);
  258. FImageCanvas.ApplyConvolution3x3(FilterGaussian3x3);
  259. UpdateView;
  260. end;
  261. end;
  262. procedure TMainForm.MenuItem38Click(Sender: TObject);
  263. begin
  264. if CheckCanvasFormat then
  265. begin
  266. FImageCanvas.CreateForImage(FImage);
  267. FImageCanvas.ApplyConvolution5x5(FilterGaussian5x5);
  268. UpdateView;
  269. end;
  270. end;
  271. procedure TMainForm.MenuItem39Click(Sender: TObject);
  272. begin
  273. if CheckCanvasFormat then
  274. begin
  275. FImageCanvas.CreateForImage(FImage);
  276. FImageCanvas.ApplyConvolution3x3(FilterSharpen3x3);
  277. UpdateView;
  278. end;
  279. end;
  280. procedure TMainForm.FormCreate(Sender: TObject);
  281. var
  282. Item: TMenuItem;
  283. Fmt: TImageFormat;
  284. Info: TImageFormatInfo;
  285. begin
  286. Caption := Format(SWindowTitle, [Imaging.GetVersionStr]);
  287. { Source image and Image's graphic are created and
  288. default image is opened.}
  289. FImage := TMultiImage.Create;
  290. FBitmap := TImagingBitmap.Create;
  291. Image.Picture.Graphic := FBitmap;
  292. FImageCanvas := TImagingCanvas.Create;
  293. { This builds Format submenu containing all possible
  294. image data formats (it dos not start at Low(TImageFormat)
  295. because there are some helper formats). Format for each item
  296. is stored in its Tag for later use in OnClick event.}
  297. for Fmt := ifIndex8 to High(TImageFormat) do
  298. begin
  299. GetImageFormatInfo(Fmt, Info);
  300. if Info.Name <> '' then
  301. begin
  302. Item := TMenuItem.Create(MainMenu);
  303. Item.Caption := Info.Name;
  304. Item.Tag := Ord(Fmt);
  305. Item.OnClick := @FormatChangeClick;
  306. FormatItem.Add(Item);
  307. end;
  308. end;
  309. if (ParamCount > 0) and FileExists(ParamStr(1)) then
  310. OpenFile(ParamStr(1))
  311. else
  312. OpenFile(GetDataDir + PathDelim + 'Tigers.jpg');
  313. end;
  314. procedure TMainForm.FormatChangeClick(Sender: TObject);
  315. begin
  316. with Sender as TMenuItem do
  317. begin
  318. FImage.Format := TImageFormat(Tag);
  319. UpdateView;
  320. end;
  321. end;
  322. procedure TMainForm.ActViewRealSizeExecute(Sender: TObject);
  323. begin
  324. ActViewRealSize.Checked := not ActViewRealSize.Checked;
  325. ActViewFitToWindow.Checked := not ActViewFitToWindow.Checked;
  326. if ActViewRealSize.Checked then
  327. begin
  328. Image.Proportional := False;
  329. Image.Stretch := False;
  330. Image.AutoSize := True;
  331. end;
  332. end;
  333. procedure TMainForm.ActViewFitToWindowExecute(Sender: TObject);
  334. begin
  335. ActViewFitToWindow.Checked := not ActViewFitToWindow.Checked;
  336. ActViewRealSize.Checked := not ActViewRealSize.Checked;
  337. if ActViewFitToWindow.Checked then
  338. begin
  339. Image.Proportional := True;
  340. Image.AutoSize := False;
  341. Image.Stretch := True;
  342. end;
  343. end;
  344. procedure TMainForm.ActViewInfoExecute(Sender: TObject);
  345. begin
  346. MessageDlg('Image Info: ' + ImageToStr(FImage.ImageDataPointer^), mtInformation, [mbOK], 0);
  347. end;
  348. procedure TMainForm.FormDestroy(Sender: TObject);
  349. begin
  350. FImageCanvas.Free;
  351. FBitmap.Free;
  352. FImage.Free;
  353. end;
  354. procedure TMainForm.ImageClick(Sender: TObject);
  355. begin
  356. ActViewInfo.Execute;
  357. end;
  358. procedure TMainForm.MenuItem3Click(Sender: TObject);
  359. begin
  360. OpenD.Filter := GetImageFileFormatsFilter(True);
  361. if OpenD.Execute then
  362. OpenFile(OpenD.FileName);
  363. end;
  364. procedure TMainForm.MenuItem40Click(Sender: TObject);
  365. begin
  366. if CheckCanvasFormat then
  367. begin
  368. FImageCanvas.CreateForImage(FImage);
  369. FImageCanvas.ApplyConvolution5x5(FilterSharpen5x5);
  370. UpdateView;
  371. end;
  372. end;
  373. procedure TMainForm.MenuItem41Click(Sender: TObject);
  374. begin
  375. if CheckCanvasFormat then
  376. begin
  377. FImageCanvas.CreateForImage(FImage);
  378. FImageCanvas.ApplyConvolution5x5(FilterGaussian5x5);
  379. FImageCanvas.ApplyConvolution5x5(FilterLaplace5x5);
  380. UpdateView;
  381. end;
  382. end;
  383. procedure TMainForm.MenuItem42Click(Sender: TObject);
  384. begin
  385. if CheckCanvasFormat then
  386. begin
  387. FImageCanvas.CreateForImage(FImage);
  388. FImageCanvas.ApplyConvolution3x3(FilterGaussian3x3);
  389. FImageCanvas.ApplyConvolution3x3(FilterSobelHorz3x3);
  390. UpdateView;
  391. end;
  392. end;
  393. procedure TMainForm.MenuItem43Click(Sender: TObject);
  394. begin
  395. if CheckCanvasFormat then
  396. begin
  397. FImageCanvas.CreateForImage(FImage);
  398. FImageCanvas.ApplyConvolution3x3(FilterGaussian3x3);
  399. FImageCanvas.ApplyConvolution3x3(FilterSobelVert3x3);
  400. UpdateView;
  401. end;
  402. end;
  403. procedure TMainForm.MenuItem44Click(Sender: TObject);
  404. begin
  405. OpenFile(FFileName);
  406. end;
  407. procedure TMainForm.MenuItem46Click(Sender: TObject);
  408. const
  409. FilterEmboss3x3: TConvolutionFilter3x3 = (
  410. Kernel: ((2, 0, 0),
  411. (0, -1, 0),
  412. (0, 0, -1));
  413. Divisor: 1);
  414. begin
  415. FImage.Format := ifGray8;
  416. FImageCanvas.CreateForImage(FImage);
  417. FImageCanvas.ApplyConvolution3x3(FilterGaussian3x3);
  418. FImageCanvas.ApplyConvolution(@FilterEmboss3x3.Kernel, 3, FilterEmboss3x3.Divisor, 0.5);
  419. UpdateView;
  420. end;
  421. procedure TMainForm.MenuItem4Click(Sender: TObject);
  422. begin
  423. FImage.Mirror;
  424. UpdateView;
  425. end;
  426. procedure TMainForm.MenuItem5Click(Sender: TObject);
  427. begin
  428. SaveD.Filter := GetImageFileFormatsFilter(False);
  429. SaveD.FileName := ChangeFileExt(ExtractFileName(FFileName), '');
  430. SaveD.FilterIndex := GetExtensionFilterIndex(GetFileExt(FFileName), False);
  431. if SaveD.Execute then
  432. begin
  433. FFileName := ChangeFileExt(SaveD.FileName, '.' + GetFilterIndexExtension(SaveD.FilterIndex, False));
  434. FImage.SaveToFile(FFileName);
  435. end;
  436. end;
  437. procedure TMainForm.MenuItem7Click(Sender: TObject);
  438. begin
  439. Close;
  440. end;
  441. procedure TMainForm.OpenFile(const FileName: string);
  442. begin
  443. FFileName := FileName;
  444. FImage.LoadMultiFromFile(FileName);
  445. SelectSubimage(0);
  446. end;
  447. procedure TMainForm.SelectSubimage(Index: LongInt);
  448. begin
  449. FImage.ActiveImage := Index;
  450. MenuItemActSubImage.Caption := Format('Active Subimage: %d/%d', [FImage.ActiveImage + 1, FImage.ImageCount]);
  451. UpdateView;
  452. end;
  453. procedure TMainForm.UpdateView;
  454. begin
  455. Image.Picture.Graphic.Assign(FImage);
  456. end;
  457. initialization
  458. {$I mainunit.lrs}
  459. {
  460. File Notes:
  461. -- TODOS ----------------------------------------------------
  462. - add more canvas stuff when it will be avaiable
  463. -- 0.19 Changes/Bug Fixes -----------------------------------
  464. - you can now open image in Imager from shell by passing
  465. path to image as parameter: 'LCLImager /home/myimage.jpg'
  466. - added Reload from File menu to reload image from disk
  467. (poor man's Undo)
  468. - added Effects menu with some convolution filters
  469. - added support for displaying of multi images
  470. -- 0.17 Changes/Bug Fixes -----------------------------------
  471. - added Nearest, Bilinear, and Bicubic filter options to
  472. Resize To 50/200% menu items
  473. - better handling of file exts when using save dialog
  474. - added rotations to Manipulate menu
  475. - now works well in Linux too
  476. -- 0.15 Changes/Bug Fixes -----------------------------------
  477. - created
  478. }
  479. end.