ImagingGraphics32.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. {
  2. Vampyre Imaging Library
  3. by Marek Mauder
  4. https://github.com/galfar/imaginglib
  5. https://imaginglib.sourceforge.io
  6. - - - - -
  7. This Source Code Form is subject to the terms of the Mozilla Public
  8. License, v. 2.0. If a copy of the MPL was not distributed with this
  9. file, You can obtain one at https://mozilla.org/MPL/2.0.
  10. }
  11. { Unit functions for converting and copying images between Imaging and Graphics32 library.}
  12. unit ImagingGraphics32;
  13. {$I ImagingOptions.inc}
  14. interface
  15. uses
  16. Types, GR32, ImagingTypes, Imaging, ImagingFormats, ImagingUtility, ImagingClasses;
  17. { Converts image from TImageData record to GR32's bitmap. Bitmap32 must be already
  18. instantiated.}
  19. procedure ConvertImageDataToBitmap32(const Image: TImageData; Bitmap32: TCustomBitmap32);
  20. { Converts image from TBaseImage instance to GR32's bitmap. Bitmap32 must be already
  21. instantiated.}
  22. procedure ConvertImageToBitmap32(Image: TBaseImage; Bitmap32: TCustomBitmap32);
  23. { Converts image data from GR32's bitmap to TImageData record.}
  24. procedure ConvertBitmap32ToImageData(Bitmap32: TCustomBitmap32; var Image: TImageData);
  25. { Converts image data from GR32's bitmap to existing TBaseImage instance.}
  26. procedure ConvertBitmap32ToImage(Bitmap32: TCustomBitmap32; Image: TBaseImage);
  27. { Copies pixels from TImageData record (with all the necessary conversion if
  28. the format is not 32bit) to existing GR32's bitmap. Both Image and Bitmap32 must
  29. have the same width and height. }
  30. procedure CopyImageDataToBitmap32(const Image: TImageData; Bitmap32: TCustomBitmap32);
  31. { Copies pixels from TBaseImage instance (with all the necessary conversion if
  32. the format is not 32bit) to existing GR32's bitmap. Both Image and Bitmap32 must
  33. have the same width and height. }
  34. procedure CopyImageToBitmap32(Image: TBaseImage; Bitmap32: TCustomBitmap32);
  35. { Copies rectangular area of pixels from TImageData record to existing GR32's bitmap.}
  36. procedure CopyRectToBitmap32(const Image: TImageData; Bitmap32: TCustomBitmap32;
  37. SrcX, SrcY, Width, Height, DstX, DstY: Integer); overload;
  38. { Copies rectangular area of pixels from TBaseImage instance to existing GR32's bitmap.}
  39. procedure CopyRectToBitmap32(Image: TBaseImage; Bitmap32: TCustomBitmap32;
  40. SrcX, SrcY, Width, Height, DstX, DstY: Integer); overload;
  41. { Maps GR32 bitmap on TImageData record so that they'll both share
  42. the same pixels in memory (Bitmap32.Bits and Image.Bits point to the same
  43. memory address). Useful if you wan to e.g. save Bitmap32 using Imaging
  44. and don't want to needlessly duplicate the entire image in memory.
  45. Note that you must not call FreeImage on Image after the mapping or
  46. the memory of Bitmap32 would be freed too.}
  47. procedure MapBitmap32ToImageData(Bitmap32: TCustomBitmap32; var Image: TImageData);
  48. implementation
  49. procedure ConvertImageDataToBitmap32(const Image: TImageData; Bitmap32: TCustomBitmap32);
  50. begin
  51. Assert(TestImage(Image));
  52. Bitmap32.SetSize(Image.Width, Image.Height);
  53. CopyImageDataToBitmap32(Image, Bitmap32);
  54. end;
  55. procedure ConvertImageToBitmap32(Image: TBaseImage; Bitmap32: TCustomBitmap32);
  56. begin
  57. ConvertImageDataToBitmap32(Image.ImageDataPointer^, Bitmap32);
  58. end;
  59. procedure ConvertBitmap32ToImageData(Bitmap32: TCustomBitmap32; var Image: TImageData);
  60. begin
  61. Assert(not Bitmap32.Empty);
  62. NewImage(Bitmap32.Width, Bitmap32.Height, ifA8R8G8B8, Image);
  63. Move(Bitmap32.Bits^, Image.Bits^, Image.Size);
  64. end;
  65. procedure ConvertBitmap32ToImage(Bitmap32: TCustomBitmap32; Image: TBaseImage);
  66. begin
  67. ConvertBitmap32ToImageData(Bitmap32, Image.ImageDataPointer^);
  68. end;
  69. procedure CopyImageDataToBitmap32(const Image: TImageData; Bitmap32: TCustomBitmap32);
  70. begin
  71. Assert(TestImage(Image) and (Image.Width = Bitmap32.Width) and (Image.Height = Bitmap32.Height));
  72. CopyRectToBitmap32(Image, Bitmap32, 0, 0, Image.Width, Image.Height, 0, 0);
  73. end;
  74. procedure CopyImageToBitmap32(Image: TBaseImage; Bitmap32: TCustomBitmap32);
  75. begin
  76. CopyImageDataToBitmap32(Image.ImageDataPointer^, Bitmap32);
  77. end;
  78. procedure CopyRectToBitmap32(const Image: TImageData; Bitmap32: TCustomBitmap32;
  79. SrcX, SrcY, Width, Height, DstX, DstY: Integer);
  80. var
  81. TempImage: TImageData;
  82. X, Y, Bpp, SrcWidthBytes, DstWidth, MoveBytes: Integer;
  83. DstPtr: PColor32Rec;
  84. SrcPtr: PByte;
  85. Info: TImageFormatInfo;
  86. begin
  87. Assert(TestImage(Image) and not Bitmap32.Empty);
  88. ClipCopyBounds(SrcX, SrcY, Width, Height, DstX, DstY, Image.Width, Image.Height,
  89. Rect(0, 0, Bitmap32.Width, Bitmap32.Height));
  90. if Image.Format in [ifIndex8, ifGray8, ifA8Gray8, ifGray16, ifR8G8B8, ifA8R8G8B8,
  91. ifR16G16B16, ifA16R16G16B16] then
  92. begin
  93. GetImageFormatInfo(Image.Format, Info);
  94. Bpp := Info.BytesPerPixel;
  95. SrcWidthBytes := Image.Width * Bpp;
  96. DstWidth := Bitmap32.Width;
  97. MoveBytes := Width * Bpp;
  98. SrcPtr := @PByteArray(Image.Bits)[SrcY * SrcWidthBytes + SrcX * Bpp];
  99. DstPtr := @PColor32RecArray(Bitmap32.Bits)[DstY * DstWidth + DstX];
  100. for Y := 0 to Height - 1 do
  101. begin
  102. case Image.Format of
  103. ifIndex8:
  104. for X := 0 to Width - 1 do
  105. begin
  106. DstPtr^ := Image.Palette[SrcPtr^];
  107. Inc(DstPtr);
  108. Inc(SrcPtr, Bpp);
  109. end;
  110. ifGray8:
  111. for X := 0 to Width - 1 do
  112. begin
  113. DstPtr.R := SrcPtr^;
  114. DstPtr.G := SrcPtr^;
  115. DstPtr.B := SrcPtr^;
  116. DstPtr.A := 255;
  117. Inc(DstPtr);
  118. Inc(SrcPtr, Bpp);
  119. end;
  120. ifA8Gray8:
  121. for X := 0 to Width - 1 do
  122. begin
  123. DstPtr.R := SrcPtr^;
  124. DstPtr.G := SrcPtr^;
  125. DstPtr.B := SrcPtr^;
  126. DstPtr.A := PWordRec(SrcPtr).High;
  127. Inc(DstPtr);
  128. Inc(SrcPtr, Bpp);
  129. end;
  130. ifGray16:
  131. for X := 0 to Width - 1 do
  132. begin
  133. DstPtr.R := PWord(SrcPtr)^ shr 8;
  134. DstPtr.G := DstPtr.R;
  135. DstPtr.B := DstPtr.R;
  136. DstPtr.A := 255;
  137. Inc(DstPtr);
  138. Inc(SrcPtr, Bpp);
  139. end;
  140. ifR8G8B8:
  141. for X := 0 to Width - 1 do
  142. begin
  143. DstPtr.Color24Rec := PColor24Rec(SrcPtr)^;
  144. DstPtr.A := 255;
  145. Inc(DstPtr);
  146. Inc(SrcPtr, Bpp);
  147. end;
  148. ifA8R8G8B8:
  149. begin
  150. Move(SrcPtr^, DstPtr^, MoveBytes);
  151. Inc(DstPtr, Width);
  152. Inc(SrcPtr, MoveBytes);
  153. end;
  154. ifR16G16B16:
  155. for X := 0 to Width - 1 do
  156. begin
  157. DstPtr.R := PColor48Rec(SrcPtr).R shr 8;
  158. DstPtr.G := PColor48Rec(SrcPtr).G shr 8;
  159. DstPtr.B := PColor48Rec(SrcPtr).B shr 8;
  160. DstPtr.A := 255;
  161. Inc(DstPtr);
  162. Inc(SrcPtr, Bpp);
  163. end;
  164. ifA16R16G16B16:
  165. for X := 0 to Width - 1 do
  166. begin
  167. DstPtr.R := PColor64Rec(SrcPtr).R shr 8;
  168. DstPtr.G := PColor64Rec(SrcPtr).G shr 8;
  169. DstPtr.B := PColor64Rec(SrcPtr).B shr 8;
  170. DstPtr.A := PColor64Rec(SrcPtr).A shr 8;
  171. Inc(DstPtr);
  172. Inc(SrcPtr, Bpp);
  173. end;
  174. end;
  175. Inc(SrcPtr, SrcWidthBytes - MoveBytes);
  176. Inc(DstPtr, DstWidth - Width);
  177. end;
  178. end
  179. else
  180. begin
  181. InitImage(TempImage);
  182. CloneImage(Image, TempImage);
  183. ConvertImage(TempImage, ifA8R8G8B8);
  184. try
  185. CopyRectToBitmap32(TempImage, Bitmap32, SrcX, SrcY, Width, Height, DstX, DstY);
  186. finally
  187. FreeImage(TempImage);
  188. end;
  189. end;
  190. end;
  191. procedure CopyRectToBitmap32(Image: TBaseImage; Bitmap32: TCustomBitmap32;
  192. SrcX, SrcY, Width, Height, DstX, DstY: Integer);
  193. begin
  194. CopyRectToBitmap32(Image.ImageDataPointer^, Bitmap32,
  195. SrcX, SrcY, Width, Height, DstX, DstY);
  196. end;
  197. procedure MapBitmap32ToImageData(Bitmap32: TCustomBitmap32; var Image: TImageData);
  198. begin
  199. Assert(not Bitmap32.Empty);
  200. FreeImage(Image);
  201. Image.Width := Bitmap32.Width;
  202. Image.Height := Bitmap32.Height;
  203. Image.Format := ifA8R8G8B8;
  204. Image.Size := Image.Width * Image.Height * 4;
  205. Image.Bits := Bitmap32.Bits;
  206. end;
  207. {
  208. File Notes:
  209. -- 0.26.5 Changes/Bug Fixes ---------------------------------
  210. - Created with initial stuff.
  211. }
  212. end.