2
0

GR32.ImageFormats.TBitmap.pas 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. unit GR32.ImageFormats.TBitmap;
  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 image format support for Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Anders Melander <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2008-2022
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$include GR32.inc}
  35. implementation
  36. uses
  37. Classes,
  38. {$ifndef FPC}
  39. Windows,
  40. {$else FPC}
  41. LCLType,
  42. {$endif FPC}
  43. Graphics,
  44. SysUtils,
  45. GR32,
  46. GR32_Backends,
  47. GR32.ImageFormats.TGraphic,
  48. GR32.ImageFormats;
  49. //------------------------------------------------------------------------------
  50. //
  51. // TImageFormatAdapterTBitmap
  52. //
  53. //------------------------------------------------------------------------------
  54. // Implements IImageFormatAdapter for the TBitmap class.
  55. //------------------------------------------------------------------------------
  56. type
  57. TImageFormatAdapterTBitmap = class(TCustomImageFormatAdapterTGraphic,
  58. IImageFormatAdapter,
  59. IImageFormatResourceReader)
  60. strict protected
  61. // IImageFormatAdapter
  62. function AssignFrom(Dest: TCustomBitmap32; Source: TPersistent): boolean; override;
  63. function AssignTo(Source: TCustomBitmap32; Dest: TPersistent): boolean; override;
  64. strict private
  65. // IImageFormatResourceReader
  66. function LoadFromResource(ADest: TCustomBitmap32; AResourceType: TResourceType; AStream: TStream): boolean;
  67. end;
  68. //------------------------------------------------------------------------------
  69. // IImageFormatAdapter
  70. //------------------------------------------------------------------------------
  71. function TImageFormatAdapterTBitmap.AssignFrom(Dest: TCustomBitmap32; Source: TPersistent): boolean;
  72. var
  73. TransparentColor: TColor32;
  74. DstP: PColor32;
  75. I: integer;
  76. DstColor: TColor32;
  77. FontSupport: IFontSupport;
  78. {$if defined(FRAMEWORK_FMX)}
  79. Data: TBitmapData;
  80. SrcP: PColor32;
  81. {$ifend}
  82. begin
  83. if (not (Source is TBitmap)) then
  84. Exit(False);
  85. Result := True;
  86. {$if not defined(FRAMEWORK_FMX)}
  87. AssignFromGraphicPlain(Dest, TBitmap(Source), 0, TBitmap(Source).PixelFormat <> pf32bit);
  88. if Dest.Empty then
  89. Exit;
  90. if TBitmap(Source).Transparent then
  91. begin
  92. TransparentColor := Color32(TBitmap(Source).TransparentColor) and $00FFFFFF;
  93. DstP := @Dest.Bits[0];
  94. for I := 0 to Dest.Width * Dest.Height - 1 do
  95. begin
  96. DstColor := DstP^ and $00FFFFFF;
  97. if DstColor = TransparentColor then
  98. DstP^ := DstColor;
  99. Inc(DstP);
  100. end;
  101. end;
  102. if Supports(Dest.Backend, IFontSupport, FontSupport) then // this is optional
  103. FontSupport.Font.Assign(TBitmap(Source).Canvas.Font);
  104. {$else}
  105. Dest.SetSize(TBitmap(Source).Width, TBitmap(Source).Height);
  106. TBitmap(Source).Map(TMapAccess.Read, Data);
  107. try
  108. for I := 0 to TBitmap(Source).Height-1 do
  109. begin
  110. SrcP := Data.GetScanline(I);
  111. DstP := Dest.GetScanline(I);
  112. Move(SrcP^, DstP^, Data.BytesPerLine);
  113. end;
  114. finally
  115. TBitmap(Source).Unmap(Data);
  116. end;
  117. {$ifend}
  118. end;
  119. //------------------------------------------------------------------------------
  120. function TImageFormatAdapterTBitmap.AssignTo(Source: TCustomBitmap32; Dest: TPersistent): boolean;
  121. var
  122. SavedBackend: TCustomBackend;
  123. FontSupport: IFontSupport;
  124. {$if defined(FRAMEWORK_FMX)}
  125. Data: TBitmapData;
  126. SrcP: PColor32;
  127. {$ifend}
  128. begin
  129. if (not (Dest is TBitmap)) then
  130. Exit(False);
  131. Result := True;
  132. RequireBackendSupport(Source, [IDeviceContextSupport], romOr, False, SavedBackend);
  133. try
  134. TBitmap(Dest).SetSize(0, 0);
  135. TBitmap(Dest).PixelFormat := pf32Bit;
  136. TBitmap(Dest).SetSize(Source.Width, Source.Height);
  137. if Supports(Source.Backend, IFontSupport, FontSupport) then // this is optional
  138. begin
  139. TBitmap(Dest).Canvas.Font.Assign(FontSupport.Font);
  140. FontSupport := nil;
  141. end;
  142. if Source.Empty then
  143. Exit;
  144. {$if not defined(FRAMEWORK_FMX)}
  145. TBitmap(Dest).Canvas.Lock;
  146. try
  147. (Source.Backend as IDeviceContextSupport).DrawTo(TBitmap(Dest).Canvas.Handle,
  148. Source.BoundsRect, Source.BoundsRect)
  149. finally
  150. TBitmap(Dest).Canvas.UnLock;
  151. end;
  152. {$else}
  153. TBitmap(Dest).SetSize(Source.Width, Source.Height);
  154. TBitmap(Dest).Map(TMapAccess.Write, Data);
  155. try
  156. for I := 0 to Source.Height-1 do
  157. begin
  158. SrcP := Source.GetScanline(I);
  159. DstP := Data.GetScanline(I);
  160. Move(SrcP^, DstP^, Data.BytesPerLine);
  161. end;
  162. finally
  163. TBitmap(Dest).Unmap(Data);
  164. end;
  165. {$ifend}
  166. finally
  167. RestoreBackend(Source, SavedBackend);
  168. end;
  169. end;
  170. //------------------------------------------------------------------------------
  171. // IImageFormatResourceReader
  172. //------------------------------------------------------------------------------
  173. type
  174. TBitmapFileHeader = packed record
  175. bfType: Word;
  176. bfSize: DWORD;
  177. bfReserved1: Word;
  178. bfReserved2: Word;
  179. bfOffBits: DWORD;
  180. end;
  181. function TImageFormatAdapterTBitmap.LoadFromResource(ADest: TCustomBitmap32; AResourceType: TResourceType;
  182. AStream: TStream): boolean;
  183. var
  184. Bitmap: TBitmap;
  185. BitmapFileHeader: TBitmapFileHeader;
  186. BitmapStream: TStream;
  187. begin
  188. if (AResourceType = RT_BITMAP) then
  189. begin
  190. // TBitmap does not have any (accesible) methods to read a DIB, so we have to
  191. // "make believe" that the stream contains a BMP file.
  192. BitmapFileHeader := Default(TBitmapFileHeader);
  193. BitmapFileHeader.bfType := $4D42;
  194. BitmapStream := TMemoryStream.Create;
  195. try
  196. TMemoryStream(BitmapStream).Size := AStream.Size + SizeOf(TBitmapFileHeader);
  197. BitmapStream.Write(BitmapFileHeader, SizeOf(TBitmapFileHeader));
  198. BitmapStream.CopyFrom(AStream, 0);
  199. BitmapStream.Position := 0;
  200. Bitmap := TBitmap.Create;
  201. try
  202. Bitmap.LoadFromStream(BitmapStream);
  203. ADest.Assign(Bitmap);
  204. finally
  205. Bitmap.Free;
  206. end;
  207. finally
  208. BitmapStream.Free;
  209. end;
  210. Result := True;
  211. end else
  212. Result := False;
  213. end;
  214. //------------------------------------------------------------------------------
  215. //------------------------------------------------------------------------------
  216. //------------------------------------------------------------------------------
  217. var
  218. ImageFormatHandle: integer = 0;
  219. initialization
  220. ImageFormatHandle := ImageFormatManager.RegisterImageFormat(TImageFormatAdapterTBitmap.Create(TBitmap), ImageFormatPriorityNormal);;
  221. finalization
  222. ImageFormatManager.UnregisterImageFormat(ImageFormatHandle);
  223. end.