ImagingFmx.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. {
  2. Vampyre Imaging Library
  3. by Marek Mauder
  4. http://imaginglib.sourceforge.net
  5. The contents of this file are used with permission, subject to the Mozilla
  6. Public License Version 1.1 (the "License"); you may not use this file except
  7. in compliance with the License. You may obtain a copy of the License at
  8. http://www.mozilla.org/MPL/MPL-1.1.html
  9. Software distributed under the License is distributed on an "AS IS" basis,
  10. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  11. the specific language governing rights and limitations under the License.
  12. Alternatively, the contents of this file may be used under the terms of the
  13. GNU Lesser General Public License (the "LGPL License"), in which case the
  14. provisions of the LGPL License are applicable instead of those above.
  15. If you wish to allow use of your version of this file only under the terms
  16. of the LGPL License and not to allow others to use your version of this file
  17. under the MPL, indicate your decision by deleting the provisions above and
  18. replace them with the notice and other provisions required by the LGPL
  19. License. If you do not delete the provisions above, a recipient may use
  20. your version of this file under either the MPL or the LGPL License.
  21. For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
  22. }
  23. { Functions and classes for interoperability between Imaging and
  24. FireMonkey framework.}
  25. unit ImagingFmx;
  26. {$I ImagingOptions.inc}
  27. interface
  28. uses
  29. Types,
  30. SysUtils,
  31. ImagingTypes,
  32. Imaging,
  33. ImagingFormats,
  34. ImagingClasses,
  35. ImagingUtility,
  36. UITypes,
  37. Fmx.Types,
  38. Fmx.Utils,
  39. Fmx.Graphics;
  40. { Converts image from TImageData record to FMX bitmap. Bitmap must be already instantiated.}
  41. procedure ConvertImageDataToFmxBitmap(const Image: TImageData; Bitmap: TBitmap);
  42. { Converts FMX bitmap to TImageData. Image Data must already instantiated.}
  43. procedure ConvertFmxBitmapToImageData(const Bitmap: TBitmap; Image: TImageData);
  44. { Converts image from TBaseImage instance to FMX bitmap. Bitmap must be already instantiated.}
  45. procedure ConvertImageToFmxBitmap(Image: TBaseImage; Bitmap: TBitmap);
  46. { Copies rectangular area of pixels from TImageData record to existing FMX bitmap.}
  47. procedure CopyRectToFmxBitmap(const Image: TImageData; Bitmap: TBitmap;
  48. SrcX, SrcY, Width, Height, DstX, DstY: LongInt); overload;
  49. { Copies rectangular area of pixels from TBaseImage instance to existing FMX bitmap.}
  50. procedure CopyRectToFmxBitmap(Image: TBaseImage; Bitmap: TBitmap;
  51. SrcX, SrcY, Width, Height, DstX, DstY: LongInt); overload;
  52. implementation
  53. procedure ConvertFmxBitmapToImageData(const Bitmap: TBitmap; Image: TImageData);
  54. var
  55. Color32: TColor32Rec;
  56. MapData: TBitmapData;
  57. SourceData: PAlphaColorRec;
  58. TargetData: PByte;
  59. X, Y, Bpp, SrcWidthBytes: Integer;
  60. TargetInfo: TImageFormatInfo;
  61. begin
  62. Bitmap.Map(TMapAccess.maRead, MapData);
  63. GetImageFormatInfo(Image.Format, TargetInfo);
  64. Bpp := TargetInfo.BytesPerPixel;
  65. SrcWidthBytes := Image.Width * Bpp;
  66. TargetData := @PByteArray(Image.Bits)[0];
  67. for Y := 0 to Pred(Bitmap.Height) do
  68. for X:= 0 to Pred(Bitmap.Width) do
  69. begin
  70. SourceData:= @PAlphaColorRecArray(MapData.Data)[Y * (MapData.Pitch div 4) + X];
  71. case TargetInfo.Format of
  72. ifIndex8:
  73. begin
  74. Image.Palette[TargetData^].R := SourceData^.R;
  75. Image.Palette[TargetData^].G := SourceData^.G;
  76. Image.Palette[TargetData^].B := SourceData^.B;
  77. Image.Palette[TargetData^].A := SourceData^.A;
  78. end;
  79. ifGray8:
  80. TargetData^ := SourceData.R;
  81. ifA8Gray8:
  82. begin
  83. TargetData^ := SourceData.R;
  84. PWordRec(TargetData).High := SourceData.A;
  85. end;
  86. ifGray16:
  87. PWord(TargetData)^ := SourceData.R;
  88. ifR8G8B8:
  89. begin
  90. PColor24Rec(TargetData)^.R := SourceData.R;
  91. PColor24Rec(TargetData)^.G := SourceData.G;
  92. PColor24Rec(TargetData)^.B := SourceData.B;
  93. end;
  94. ifA8R8G8B8:
  95. begin
  96. PColor32Rec(TargetData)^.A := SourceData^.B;
  97. PColor32Rec(TargetData)^.G := SourceData^.R;
  98. PColor32Rec(TargetData)^.R := SourceData^.G;
  99. PColor32Rec(TargetData)^.B := SourceData^.A;
  100. end;
  101. ifR16G16B16:
  102. begin
  103. PColor48Rec(TargetData).R := Round(SourceData.R * $FFFF / 255);
  104. PColor48Rec(TargetData).G := Round(SourceData.G * $FFFF / 255);
  105. PColor48Rec(TargetData).B := Round(SourceData.B * $FFFF / 255);
  106. end;
  107. ifA16R16G16B16:
  108. begin
  109. PColor64Rec(TargetData).R := Round(SourceData.R * $FFFF / 255);
  110. PColor64Rec(TargetData).G := Round(SourceData.G * $FFFF / 255);
  111. PColor64Rec(TargetData).B := Round(SourceData.B * $FFFF / 255);
  112. PColor64Rec(TargetData).A := Round(SourceData.A * $FFFF / 255);
  113. end;
  114. else
  115. Color32.R := SourceData^.R;
  116. Color32.G := SourceData^.G;
  117. Color32.B := SourceData^.B;
  118. Color32.A := SourceData^.A;
  119. TargetInfo.SetPixel32(TargetData,@TargetInfo, Image.Palette,Color32);
  120. end;
  121. Inc(TargetData, Bpp);
  122. end;
  123. Bitmap.Unmap(MapData);
  124. end;
  125. procedure ConvertImageDataToFmxBitmap(const Image: TImageData; Bitmap: TBitmap);
  126. begin
  127. Assert(TestImage(Image));
  128. Bitmap.SetSize(Image.Width, Image.Height);
  129. CopyRectToFmxBitmap(Image, Bitmap, 0, 0, Image.Width, Image.Height, 0, 0);
  130. end;
  131. procedure ConvertImageToFmxBitmap(Image: TBaseImage; Bitmap: TBitmap);
  132. begin
  133. ConvertImageDataToFmxBitmap(Image.ImageDataPointer^, Bitmap);
  134. end;
  135. procedure ConvertToAlphaColorRec(SrcPix: PByte; DestPix: PAlphaColorRec;
  136. const SrcInfo: TImageFormatInfo; SrcPalette: PPalette32);
  137. var
  138. Color32:TColor32Rec;
  139. begin
  140. case SrcInfo.Format of
  141. ifIndex8:
  142. begin
  143. DestPix^.R := SrcPalette[SrcPix^].R;
  144. DestPix^.G := SrcPalette[SrcPix^].G;
  145. DestPix^.B := SrcPalette[SrcPix^].B;
  146. DestPix^.A := SrcPalette[SrcPix^].A;
  147. end;
  148. ifGray8:
  149. begin
  150. DestPix.R := SrcPix^;
  151. DestPix.G := SrcPix^;
  152. DestPix.B := SrcPix^;
  153. DestPix.A := 255;
  154. end;
  155. ifA8Gray8:
  156. begin
  157. DestPix.R := SrcPix^;
  158. DestPix.G := SrcPix^;
  159. DestPix.B := SrcPix^;
  160. DestPix.A := PWordRec(SrcPix).High;
  161. end;
  162. ifGray16:
  163. begin
  164. DestPix.R := PWord(SrcPix)^ shr 8;
  165. DestPix.G := DestPix.R;
  166. DestPix.B := DestPix.R;
  167. DestPix.A := 255;
  168. end;
  169. ifR8G8B8:
  170. begin
  171. DestPix.R := PColor24Rec(SrcPix)^.R;
  172. DestPix.G := PColor24Rec(SrcPix)^.G;
  173. DestPix.B := PColor24Rec(SrcPix)^.B;
  174. DestPix.A := 255;
  175. end;
  176. ifA8R8G8B8:
  177. begin
  178. DestPix^.R := PColor32Rec(SrcPix)^.R;
  179. DestPix^.G := PColor32Rec(SrcPix)^.G;
  180. DestPix^.B := PColor32Rec(SrcPix)^.B;
  181. DestPix^.A := PColor32Rec(SrcPix)^.A;
  182. end;
  183. ifR16G16B16:
  184. begin
  185. DestPix.R := PColor48Rec(SrcPix).R shr 8;
  186. DestPix.G := PColor48Rec(SrcPix).G shr 8;
  187. DestPix.B := PColor48Rec(SrcPix).B shr 8;
  188. DestPix.A := 255;
  189. end;
  190. ifA16R16G16B16:
  191. begin
  192. DestPix.R := PColor64Rec(SrcPix).R shr 8;
  193. DestPix.G := PColor64Rec(SrcPix).G shr 8;
  194. DestPix.B := PColor64Rec(SrcPix).B shr 8;
  195. DestPix.A := PColor64Rec(SrcPix).A shr 8;
  196. end;
  197. else
  198. Color32:=SrcInfo.GetPixel32(SrcPix, @SrcInfo, SrcPalette);
  199. DestPix^.R := Color32.R;
  200. DestPix^.G := Color32.G;
  201. DestPix^.B := Color32.B;
  202. DestPix^.A := Color32.A;
  203. end;
  204. end;
  205. procedure CopyRectToFmxBitmap(const Image: TImageData; Bitmap: TBitmap;
  206. SrcX, SrcY, Width, Height, DstX, DstY: LongInt);
  207. var
  208. TempImage: TImageData;
  209. X, Y, Bpp, SrcWidthBytes, MoveBytes: Integer;
  210. SrcPtr: PByte;
  211. Info: TImageFormatInfo;
  212. MapData: TBitmapData;
  213. DstPtr: PAlphaColorRec;
  214. ARGB: TAlphaColorRec;
  215. begin
  216. Assert(TestImage(Image) and not Bitmap.IsEmpty);
  217. ClipCopyBounds(SrcX, SrcY, Width, Height, DstX, DstY, Image.Width, Image.Height,
  218. Rect(0, 0, Bitmap.Width, Bitmap.Height));
  219. GetImageFormatInfo(Image.Format, Info);
  220. if not Info.IsSpecial then
  221. begin
  222. Bpp := Info.BytesPerPixel;
  223. SrcWidthBytes := Image.Width * Bpp;
  224. MoveBytes := Width * Bpp;
  225. SrcPtr := @PByteArray(Image.Bits)[SrcY * SrcWidthBytes + SrcX * Bpp];
  226. Bitmap.Map(TMapAccess.maReadWrite, MapData);
  227. for Y := 0 to Height - 1 do
  228. begin
  229. if Info.Format = ifA8R8G8B8 then
  230. begin
  231. for X := 0 to Pred(Width) do
  232. begin
  233. DstPtr := @PColor32RecArray(MapData.Data)[Y * (MapData.Pitch div 4) + X];
  234. Move(SrcPtr^, ARGB, 4);
  235. DstPtr^.A := ARGB.A;
  236. DstPtr^.R := ARGB.R;
  237. DstPtr^.G := ARGB.G;
  238. DstPtr^.B := ARGB.B;
  239. Inc(SrcPtr, 4);
  240. end;
  241. end
  242. else
  243. begin
  244. for X := 0 to Width - 1 do
  245. begin
  246. DstPtr := @PColor32RecArray(MapData.Data)[Y * (MapData.Pitch div 4)+X];
  247. ConvertToAlphaColorRec(SrcPtr, DstPtr, Info, Image.Palette);
  248. Inc(SrcPtr, Bpp);
  249. end;
  250. end;
  251. end;
  252. end
  253. else
  254. begin
  255. InitImage(TempImage);
  256. CloneImage(Image, TempImage);
  257. ConvertImage(TempImage, ifA8R8G8B8);
  258. try
  259. CopyRectToFmxBitmap(TempImage, Bitmap, SrcX, SrcY, Width, Height, DstX, DstY);
  260. finally
  261. FreeImage(TempImage);
  262. end;
  263. end;
  264. Bitmap.UnMap(MapData);
  265. end;
  266. procedure CopyRectToFmxBitmap(Image: TBaseImage; Bitmap: TBitmap;
  267. SrcX, SrcY, Width, Height, DstX, DstY: LongInt);
  268. begin
  269. CopyRectToFmxBitmap(Image.ImageDataPointer^, Bitmap,
  270. SrcX, SrcY, Width, Height, DstX, DstY);
  271. end;
  272. {
  273. File Notes:
  274. -- TODOS ----------------------------------------------------
  275. - nothing now
  276. -- 0.77.1 Changes/Bug Fixes ---------------------------------
  277. - Removed support for old FMX versions (XE2 etc.)
  278. - Support for current FMX version (XE4+) contributed by Ken Schafer.
  279. -- 0.77 Changes/Bug Fixes -----------------------------------
  280. - Unit created with initial stuff, working with FMX1 in Delphi XE2.
  281. }
  282. end.