2 Vampyre Imaging Library
4 http://imaginglib.sourceforge.net
6 The contents of this file are used with permission, subject to the Mozilla
7 Public License Version 1.1 (the "License"); you may not use this file except
8 in compliance with the License. You may obtain a copy of the License at
9 http://www.mozilla.org/MPL/MPL-1.1.html
11 Software distributed under the License is distributed on an "AS IS" basis,
12 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
13 the specific language governing rights and limitations under the License.
15 Alternatively, the contents of this file may be used under the terms of the
16 GNU Lesser General Public License (the "LGPL License"), in which case the
17 provisions of the LGPL License are applicable instead of those above.
18 If you wish to allow use of your version of this file only under the terms
19 of the LGPL License and not to allow others to use your version of this file
20 under the MPL, indicate your decision by deleting the provisions above and
21 replace them with the notice and other provisions required by the LGPL
22 License. If you do not delete the provisions above, a recipient may use
23 your version of this file under either the MPL or the LGPL License.
25 For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
28 { This unit contains VCL/LCL TGraphic descendant which uses Imaging library
29 for saving and loading.}
30 unit ImagingComponents
;
32 {$I ImagingOptions.inc}
37 {$DEFINE COMPONENT_SET_LCL}
38 {$UNDEF COMPONENT_SET_VCL}
41 {$IF not Defined(COMPONENT_SET_LCL) and not Defined(COMPONENT_SET_VCL)}
42 // If no component sets should be used just include empty unit.
49 SysUtils
, Types
, Classes
,
53 {$IFDEF COMPONENT_SET_VCL}
56 {$IFDEF COMPONENT_SET_LCL}
63 ImagingTypes
, Imaging
, ImagingClasses
;
66 { Graphic class which uses Imaging to load images.
67 It has standard TBitmap class as ancestor and it can
68 Assign also to/from TImageData structres and TBaseImage
69 classes. For saving is uses inherited TBitmap methods.
70 This class is automatically registered to TPicture for all
71 file extensions supported by Imaging (useful only for loading).
72 If you just want to load images in various formats you can use this
73 class or simply use TPicture.LoadFromXXX which will create this class
74 automatically. For TGraphic class that saves with Imaging look
75 at TImagingGraphicForSave class.}
76 TImagingGraphic
= class(TBitmap
)
78 procedure ReadDataFromStream(Stream
: TStream
); virtual;
79 procedure AssignTo(Dest
: TPersistent
); override;
81 constructor Create
; override;
83 { Loads new image from the stream. It can load all image
84 file formats supported by Imaging (and enabled of course)
85 even though it is called by descendant class capable of
86 saving only one file format.}
87 procedure LoadFromStream(Stream
: TStream
); override;
88 { Copies the image contained in Source to this graphic object.
89 Supports also TBaseImage descendants from ImagingClasses unit. }
90 procedure Assign(Source
: TPersistent
); override;
91 { Copies the image contained in TBaseImage to this graphic object.}
92 procedure AssignFromImage(Image
: TBaseImage
);
93 { Copies the current image to TBaseImage object.}
94 procedure AssignToImage(Image
: TBaseImage
);
95 { Copies the image contained in TImageData structure to this graphic object.}
96 procedure AssignFromImageData(const ImageData
: TImageData
);
97 { Copies the current image to TImageData structure.}
98 procedure AssignToImageData(var ImageData
: TImageData
);
101 TImagingGraphicClass
= class of TImagingGraphic
;
103 { Base class for file format specific TGraphic classes that use
104 Imaging for saving. Each descendant class can load all file formats
105 supported by Imaging but save only one format (TImagingBitmap
106 for *.bmp, TImagingJpeg for *.jpg). Format specific classes also
107 allow easy access to Imaging options that affect saving of files
108 (they are properties here).}
109 TImagingGraphicForSave
= class(TImagingGraphic
)
111 FDefaultFileExt
: string;
112 FSavingFormat
: TImageFormat
;
113 procedure WriteDataToStream(Stream
: TStream
); virtual;
115 constructor Create
; override;
116 { Saves the current image to the stream. It is saved in the
117 file format according to the DefaultFileExt property.
118 So each descendant class can save some other file format.}
119 procedure SaveToStream(Stream
: TStream
); override;
120 { Returns TImageFileFormat descendant for this graphic class.}
121 class function GetFileFormat
: TImageFileFormat
; virtual; abstract;
122 {$IFDEF COMPONENT_SET_LCL}
123 { Returns file extensions of this graphic class.}
124 class function GetFileExtensions
: string; override;
125 { Returns default MIME type of this graphic class.}
126 function GetMimeType
: string; override;
128 { Default (the most common) file extension of this graphic class.}
129 property DefaultFileExt
: string read FDefaultFileExt
;
132 TImagingGraphicForSaveClass
= class of TImagingGraphicForSave
;
134 {$IFNDEF DONT_LINK_BITMAP}
135 { TImagingGraphic descendant for loading/saving Windows bitmaps.
136 VCL/CLX/LCL all have native support for bitmaps so you might
137 want to disable this class (although you can save bitmaps with
138 RLE compression with this class).}
139 TImagingBitmap
= class(TImagingGraphicForSave
)
143 constructor Create
; override;
144 procedure SaveToStream(Stream
: TStream
); override;
145 class function GetFileFormat
: TImageFileFormat
; override;
146 { See ImagingBitmapRLE option for details.}
147 property UseRLE
: Boolean read FUseRLE write FUseRLE
;
151 {$IFNDEF DONT_LINK_JPEG}
152 { TImagingGraphic descendant for loading/saving JPEG images.}
153 TImagingJpeg
= class(TImagingGraphicForSave
)
156 FProgressive
: Boolean;
158 constructor Create
; override;
159 procedure SaveToStream(Stream
: TStream
); override;
160 class function GetFileFormat
: TImageFileFormat
; override;
161 {$IFDEF COMPONENT_SET_LCL}
162 function GetMimeType
: string; override;
164 { See ImagingJpegQuality option for details.}
165 property Quality
: LongInt read FQuality write FQuality
;
166 { See ImagingJpegProgressive option for details.}
167 property Progressive
: Boolean read FProgressive write FProgressive
;
171 {$IFNDEF DONT_LINK_PNG}
172 { TImagingGraphic descendant for loading/saving PNG images.}
173 TImagingPNG
= class(TImagingGraphicForSave
)
176 FCompressLevel
: LongInt;
178 constructor Create
; override;
179 procedure SaveToStream(Stream
: TStream
); override;
180 class function GetFileFormat
: TImageFileFormat
; override;
181 { See ImagingPNGPreFilter option for details.}
182 property PreFilter
: LongInt read FPreFilter write FPreFilter
;
183 { See ImagingPNGCompressLevel option for details.}
184 property CompressLevel
: LongInt read FCompressLevel write FCompressLevel
;
188 {$IFNDEF DONT_LINK_GIF}
189 { TImagingGraphic descendant for loading/saving GIF images.}
190 TImagingGIF
= class(TImagingGraphicForSave
)
192 class function GetFileFormat
: TImageFileFormat
; override;
196 {$IFNDEF DONT_LINK_TARGA}
197 { TImagingGraphic descendant for loading/saving Targa images.}
198 TImagingTarga
= class(TImagingGraphicForSave
)
202 constructor Create
; override;
203 procedure SaveToStream(Stream
: TStream
); override;
204 class function GetFileFormat
: TImageFileFormat
; override;
205 { See ImagingTargaRLE option for details.}
206 property UseRLE
: Boolean read FUseRLE write FUseRLE
;
210 {$IFNDEF DONT_LINK_DDS}
211 { Compresssion type used when saving DDS files by TImagingDds.}
212 TDDSCompresion
= (dcNone
, dcDXT1
, dcDXT3
, dcDXT5
);
214 { TImagingGraphic descendant for loading/saving DDS images.}
215 TImagingDDS
= class(TImagingGraphicForSave
)
217 FCompression
: TDDSCompresion
;
219 constructor Create
; override;
220 procedure SaveToStream(Stream
: TStream
); override;
221 class function GetFileFormat
: TImageFileFormat
; override;
222 { You can choose compression type used when saving DDS file.
223 dcNone means that file will be saved in the current bitmaps pixel format.}
224 property Compression
: TDDSCompresion read FCompression write FCompression
;
228 {$IFNDEF DONT_LINK_MNG}
229 { TImagingGraphic descendant for loading/saving MNG images.}
230 TImagingMNG
= class(TImagingGraphicForSave
)
232 FLossyCompression
: Boolean;
233 FLossyAlpha
: Boolean;
235 FCompressLevel
: LongInt;
237 FProgressive
: Boolean;
239 constructor Create
; override;
240 procedure SaveToStream(Stream
: TStream
); override;
241 class function GetFileFormat
: TImageFileFormat
; override;
242 {$IFDEF COMPONENT_SET_LCL}
243 function GetMimeType
: string; override;
245 { See ImagingMNGLossyCompression option for details.}
246 property LossyCompression
: Boolean read FLossyCompression write FLossyCompression
;
247 { See ImagingMNGLossyAlpha option for details.}
248 property LossyAlpha
: Boolean read FLossyAlpha write FLossyAlpha
;
249 { See ImagingMNGPreFilter option for details.}
250 property PreFilter
: LongInt read FPreFilter write FPreFilter
;
251 { See ImagingMNGCompressLevel option for details.}
252 property CompressLevel
: LongInt read FCompressLevel write FCompressLevel
;
253 { See ImagingMNGQuality option for details.}
254 property Quality
: LongInt read FQuality write FQuality
;
255 { See ImagingMNGProgressive option for details.}
256 property Progressive
: Boolean read FProgressive write FProgressive
;
260 {$IFNDEF DONT_LINK_JNG}
261 { TImagingGraphic descendant for loading/saving JNG images.}
262 TImagingJNG
= class(TImagingGraphicForSave
)
264 FLossyAlpha
: Boolean;
265 FAlphaPreFilter
: LongInt;
266 FAlphaCompressLevel
: LongInt;
268 FProgressive
: Boolean;
270 constructor Create
; override;
271 procedure SaveToStream(Stream
: TStream
); override;
272 class function GetFileFormat
: TImageFileFormat
; override;
273 { See ImagingJNGLossyAlpha option for details.}
274 property LossyAlpha
: Boolean read FLossyAlpha write FLossyAlpha
;
275 { See ImagingJNGPreFilter option for details.}
276 property AlphaPreFilter
: LongInt read FAlphaPreFilter write FAlphaPreFilter
;
277 { See ImagingJNGCompressLevel option for details.}
278 property AlphaCompressLevel
: LongInt read FAlphaCompressLevel write FAlphaCompressLevel
;
279 { See ImagingJNGQuality option for details.}
280 property Quality
: LongInt read FQuality write FQuality
;
281 { See ImagingJNGProgressive option for details.}
282 property Progressive
: Boolean read FProgressive write FProgressive
;
286 { Returns bitmap pixel format with the closest match with given data format.}
287 function DataFormatToPixelFormat(Format
: TImageFormat
): TPixelFormat
;
288 { Returns data format with closest match with given bitmap pixel format.}
289 function PixelFormatToDataFormat(Format
: TPixelFormat
): TImageFormat
;
291 { Converts TImageData structure to VCL/CLX/LCL bitmap.}
292 procedure ConvertDataToBitmap(const Data
: TImageData
; Bitmap
: TBitmap
);
293 { Converts VCL/CLX/LCL bitmap to TImageData structure.}
294 procedure ConvertBitmapToData(Bitmap
: TBitmap
; var Data
: TImageData
);
295 { Converts TBaseImage instance to VCL/CLX/LCL bitmap.}
296 procedure ConvertImageToBitmap(Image
: TBaseImage
; Bitmap
: TBitmap
);
297 { Converts VCL/CLX/LCL bitmap to TBaseImage. Image must exist before
298 procedure is called. It overwrites its current image data.
299 When Image is TMultiImage only the current image level is overwritten.}
300 procedure ConvertBitmapToImage(Bitmap
: TBitmap
; Image
: TBaseImage
);
302 { Displays image stored in TImageData structure onto TCanvas. This procedure
303 draws image without converting from Imaging format to TBitmap.
304 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
305 when you want displaying images that change frequently (because converting to
306 TBitmap by ConvertImageDataToBitmap is generally slow). Dest and Src
307 rectangles represent coordinates in the form (X1, Y1, X2, Y2).}
308 procedure DisplayImageData(DstCanvas
: TCanvas
; const DstRect
: TRect
; const ImageData
: TImageData
; const SrcRect
: TRect
);
309 { Displays image onto TCanvas at position [DstX, DstY]. This procedure
310 draws image without converting from Imaging format to TBitmap.
311 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
312 when you want displaying images that change frequently (because converting to
313 TBitmap by ConvertImageDataToBitmap is generally slow).}
314 procedure DisplayImage(DstCanvas
: TCanvas
; DstX
, DstY
: LongInt; Image
: TBaseImage
); overload
;
315 { Displays image onto TCanvas to rectangle DstRect. This procedure
316 draws image without converting from Imaging format to TBitmap.
317 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
318 when you want displaying images that change frequently (because converting to
319 TBitmap by ConvertImageDataToBitmap is generally slow).}
320 procedure DisplayImage(DstCanvas
: TCanvas
; const DstRect
: TRect
; Image
: TBaseImage
); overload
;
321 { Displays part of the image specified by SrcRect onto TCanvas to rectangle DstRect.
322 This procedure draws image without converting from Imaging format to TBitmap.
323 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
324 when you want displaying images that change frequently (because converting to
325 TBitmap by ConvertImageDataToBitmap is generally slow).}
326 procedure DisplayImage(DstCanvas
: TCanvas
; const DstRect
: TRect
; Image
: TBaseImage
; const SrcRect
: TRect
); overload
;
329 { Displays image stored in TImageData structure onto Windows device context.
330 Behaviour is the same as of DisplayImageData.}
331 procedure DisplayImageDataOnDC(DC
: HDC
; const DstRect
: TRect
; const ImageData
: TImageData
; const SrcRect
: TRect
);
338 {$IF Defined(LCLGTK2)}
339 GLib2
, GDK2
, GTK2
, GTK2Def
, GTK2Proc
,
342 {$IFNDEF DONT_LINK_BITMAP}
345 {$IFNDEF DONT_LINK_JPEG}
348 {$IFNDEF DONT_LINK_GIF}
351 {$IFNDEF DONT_LINK_TARGA}
354 {$IFNDEF DONT_LINK_DDS}
357 {$IF not Defined(DONT_LINK_PNG) or not Defined(DONT_LINK_MNG) or not Defined(DONT_LINK_JNG)}
358 ImagingNetworkGraphics
,
360 ImagingFormats
, ImagingUtility
;
363 SBadFormatDataToBitmap
= 'Cannot find compatible bitmap format for image %s';
364 SBadFormatBitmapToData
= 'Cannot find compatible data format for bitmap %p';
365 SBadFormatDisplay
= 'Unsupported image format passed';
366 SUnsupportedLCLWidgetSet
= 'This function is not implemented for current LCL widget set';
367 SImagingGraphicName
= 'Imaging Graphic AllInOne';
369 { Registers types to VCL/LCL.}
370 procedure RegisterTypes
;
374 procedure RegisterFileFormatAllInOne(Format
: TImageFileFormat
);
378 for I
:= 0 to Format
.Extensions
.Count
- 1 do
379 TPicture
.RegisterFileFormat(Format
.Extensions
[I
], SImagingGraphicName
,
383 procedure RegisterFileFormat(AClass
: TImagingGraphicForSaveClass
);
387 for I
:= 0 to AClass
.GetFileFormat
.Extensions
.Count
- 1 do
388 TPicture
.RegisterFileFormat(AClass
.GetFileFormat
.Extensions
[I
],
389 AClass
.GetFileFormat
.Name
, AClass
);
393 for I
:= Imaging
.GetFileFormatCount
- 1 downto 0 do
394 RegisterFileFormatAllInOne(Imaging
.GetFileFormatAtIndex(I
));
395 Classes
.RegisterClass(TImagingGraphic
);
397 {$IFNDEF DONT_LINK_TARGA}
398 RegisterFileFormat(TImagingTarga
);
399 Classes
.RegisterClass(TImagingTarga
);
401 {$IFNDEF DONT_LINK_DDS}
402 RegisterFileFormat(TImagingDDS
);
403 Classes
.RegisterClass(TImagingDDS
);
405 {$IFNDEF DONT_LINK_JNG}
406 RegisterFileFormat(TImagingJNG
);
407 Classes
.RegisterClass(TImagingJNG
);
409 {$IFNDEF DONT_LINK_MNG}
410 RegisterFileFormat(TImagingMNG
);
411 Classes
.RegisterClass(TImagingMNG
);
413 {$IFNDEF DONT_LINK_GIF}
414 RegisterFileFormat(TImagingGIF
);
415 Classes
.RegisterClass(TImagingGIF
);
417 {$IFNDEF DONT_LINK_PNG}
418 {$IFDEF COMPONENT_SET_LCL}
419 // Unregister Lazarus“ default PNG loader which crashes on some PNG files
420 TPicture
.UnregisterGraphicClass(TPortableNetworkGraphic
);
422 RegisterFileFormat(TImagingPNG
);
423 Classes
.RegisterClass(TImagingPNG
);
425 {$IFNDEF DONT_LINK_JPEG}
426 RegisterFileFormat(TImagingJpeg
);
427 Classes
.RegisterClass(TImagingJpeg
);
429 {$IFNDEF DONT_LINK_BITMAP}
430 RegisterFileFormat(TImagingBitmap
);
431 Classes
.RegisterClass(TImagingBitmap
);
435 { Unregisters types from VCL/LCL.}
436 procedure UnRegisterTypes
;
438 {$IFNDEF DONT_LINK_BITMAP}
439 TPicture
.UnregisterGraphicClass(TImagingBitmap
);
440 Classes
.UnRegisterClass(TImagingBitmap
);
442 {$IFNDEF DONT_LINK_JPEG}
443 TPicture
.UnregisterGraphicClass(TImagingJpeg
);
444 Classes
.UnRegisterClass(TImagingJpeg
);
446 {$IFNDEF DONT_LINK_PNG}
447 TPicture
.UnregisterGraphicClass(TImagingPNG
);
448 Classes
.UnRegisterClass(TImagingPNG
);
450 {$IFNDEF DONT_LINK_GIF}
451 TPicture
.UnregisterGraphicClass(TImagingGIF
);
452 Classes
.UnRegisterClass(TImagingGIF
);
454 {$IFNDEF DONT_LINK_TARGA}
455 TPicture
.UnregisterGraphicClass(TImagingTarga
);
456 Classes
.UnRegisterClass(TImagingTarga
);
458 {$IFNDEF DONT_LINK_DDS}
459 TPicture
.UnregisterGraphicClass(TImagingDDS
);
460 Classes
.UnRegisterClass(TImagingDDS
);
462 TPicture
.UnregisterGraphicClass(TImagingGraphic
);
463 Classes
.UnRegisterClass(TImagingGraphic
);
466 function DataFormatToPixelFormat(Format
: TImageFormat
): TPixelFormat
;
469 {$IFDEF COMPONENT_SET_VCL}
470 ifIndex8
: Result
:= pf8bit
;
471 ifR5G6B5
: Result
:= pf16bit
;
472 ifR8G8B8
: Result
:= pf24bit
;
475 ifX8R8G8B8
: Result
:= pf32bit
;
481 function PixelFormatToDataFormat(Format
: TPixelFormat
): TImageFormat
;
484 pf8bit
: Result
:= ifIndex8
;
485 pf15bit
: Result
:= ifA1R5G5B5
;
486 pf16bit
: Result
:= ifR5G6B5
;
487 pf24bit
: Result
:= ifR8G8B8
;
488 pf32bit
: Result
:= ifA8R8G8B8
;
494 procedure ConvertDataToBitmap(const Data
: TImageData
; Bitmap
: TBitmap
);
496 I
, LineBytes
: LongInt;
498 Info
: TImageFormatInfo
;
499 WorkData
: TImageData
;
500 {$IFDEF COMPONENT_SET_VCL}
501 LogPalette
: TMaxLogPalette
;
503 {$IFDEF COMPONENT_SET_LCL}
505 ImgHandle
, ImgMaskHandle
: HBitmap
;
508 PF
:= DataFormatToPixelFormat(Data
.Format
);
509 GetImageFormatInfo(Data
.Format
, Info
);
511 if (PF
= pf8bit
) and PaletteHasAlpha(Data
.Palette
, Info
.PaletteEntries
) then
513 // Some indexed images may have valid alpha data, dont lose it!
514 // (e.g. transparent 8bit PNG or GIF images)
518 if PF
= pfCustom
then
520 // Convert from formats not supported by Graphics unit
521 Imaging
.InitImage(WorkData
);
522 Imaging
.CloneImage(Data
, WorkData
);
523 if Info
.IsFloatingPoint
or Info
.HasAlphaChannel
or Info
.IsSpecial
then
524 Imaging
.ConvertImage(WorkData
, ifA8R8G8B8
)
527 {$IFDEF COMPONENT_SET_VCL}
528 if Info
.IsIndexed
or Info
.HasGrayChannel
then
529 Imaging
.ConvertImage(WorkData
, ifIndex8
)
530 else if Info
.UsePixelFormat
then
531 Imaging
.ConvertImage(WorkData
, ifR5G6B5
)
533 Imaging
.ConvertImage(WorkData
, ifR8G8B8
);
535 Imaging
.ConvertImage(WorkData
, ifA8R8G8B8
);
539 PF
:= DataFormatToPixelFormat(WorkData
.Format
);
540 GetImageFormatInfo(WorkData
.Format
, Info
);
545 if PF
= pfCustom
then
546 RaiseImaging(SBadFormatDataToBitmap
, [ImageToStr(WorkData
)]);
548 LineBytes
:= WorkData
.Width
* Info
.BytesPerPixel
;
550 {$IFDEF COMPONENT_SET_VCL}
551 Bitmap
.Width
:= WorkData
.Width
;
552 Bitmap
.Height
:= WorkData
.Height
;
553 Bitmap
.PixelFormat
:= PF
;
555 if (PF
= pf8bit
) and (WorkData
.Palette
<> nil) then
557 // Copy palette, this must be done before copying bits
558 FillChar(LogPalette
, SizeOf(LogPalette
), 0);
559 LogPalette
.palVersion
:= $300;
560 LogPalette
.palNumEntries
:= Info
.PaletteEntries
;
561 for I
:= 0 to Info
.PaletteEntries
- 1 do
564 palPalEntry
[I
].peRed
:= WorkData
.Palette
[I
].R
;
565 palPalEntry
[I
].peGreen
:= WorkData
.Palette
[I
].G
;
566 palPalEntry
[I
].peBlue
:= WorkData
.Palette
[I
].B
;
568 Bitmap
.Palette
:= CreatePalette(PLogPalette(@LogPalette
)^);
571 for I
:= 0 to WorkData
.Height
- 1 do
572 Move(PByteArray(WorkData
.Bits
)[I
* LineBytes
], Bitmap
.Scanline
[I
]^, LineBytes
);
574 // Delphi 2009 and newer support alpha transparency fro TBitmap
575 {$IF Defined(DELPHI) and (CompilerVersion >= 20.0)}
576 if Bitmap
.PixelFormat
= pf32bit
then
577 Bitmap
.AlphaFormat
:= afDefined
;
581 {$IFDEF COMPONENT_SET_LCL}
582 // Create 32bit raw image from image data
583 FillChar(RawImage
, SizeOf(RawImage
), 0);
584 with RawImage
.Description
do
586 Width
:= WorkData
.Width
;
587 Height
:= WorkData
.Height
;
590 LineEnd
:= rileDWordBoundary
;
591 BitOrder
:= riboBitsInOrder
;
592 ByteOrder
:= riboLSBFirst
;
593 LineOrder
:= riloTopToBottom
;
602 Depth
:= 32; // Must be 32 for alpha blending (and for working in MacOSX Carbon)
604 RawImage
.Data
:= WorkData
.Bits
;
605 RawImage
.DataSize
:= WorkData
.Size
;
607 // Create bitmap from raw image
608 if RawImage_CreateBitmaps(RawImage
, ImgHandle
, ImgMaskHandle
) then
610 Bitmap
.Handle
:= ImgHandle
;
611 Bitmap
.MaskHandle
:= ImgMaskHandle
;
614 if WorkData
.Bits
<> Data
.Bits
then
615 Imaging
.FreeImage(WorkData
);
618 procedure ConvertBitmapToData(Bitmap
: TBitmap
; var Data
: TImageData
);
620 I
, LineBytes
: LongInt;
621 Format
: TImageFormat
;
622 Info
: TImageFormatInfo
;
623 {$IFDEF COMPONENT_SET_VCL}
625 LogPalette
: TMaxLogPalette
;
627 {$IFDEF COMPONENT_SET_LCL}
629 LineLazBytes
: LongInt;
632 {$IFDEF COMPONENT_SET_LCL}
633 // In the current Lazarus 0.9.10 Bitmap.PixelFormat property is useless.
634 // We cannot change bitmap's format by changing it (it will just release
635 // old image but not convert it to new format) nor we can determine bitmaps's
636 // current format (it is usually set to pfDevice). So bitmap's format is obtained
637 // trough RawImage api and cannot be changed to mirror some Imaging format
638 // (so formats with no coresponding Imaging format cannot be saved now).
640 if RawImage_DescriptionFromBitmap(Bitmap
.Handle
, RawImage
.Description
) then
641 case RawImage
.Description
.BitsPerPixel
of
642 8: Format
:= ifIndex8
;
644 if RawImage
.Description
.Depth
= 15 then
648 24: Format
:= ifR8G8B8
;
649 32: Format
:= ifA8R8G8B8
;
650 48: Format
:= ifR16G16B16
;
651 64: Format
:= ifA16R16G16B16
;
656 Format
:= PixelFormatToDataFormat(Bitmap
.PixelFormat
);
657 if Format
= ifUnknown
then
659 // Convert from formats not supported by Imaging (1/4 bit)
660 if Bitmap
.PixelFormat
< pf8bit
then
661 Bitmap
.PixelFormat
:= pf8bit
663 Bitmap
.PixelFormat
:= pf32bit
;
664 Format
:= PixelFormatToDataFormat(Bitmap
.PixelFormat
);
668 if Format
= ifUnknown
then
669 RaiseImaging(SBadFormatBitmapToData
, []);
671 Imaging
.NewImage(Bitmap
.Width
, Bitmap
.Height
, Format
, Data
);
672 GetImageFormatInfo(Data
.Format
, Info
);
673 LineBytes
:= Data
.Width
* Info
.BytesPerPixel
;
675 {$IFDEF COMPONENT_SET_VCL}
676 if (Format
= ifIndex8
) and (GetObject(Bitmap
.Palette
, SizeOf(Colors
),
680 GetPaletteEntries(Bitmap
.Palette
, 0, Colors
, LogPalette
.palPalEntry
);
681 if Colors
> Info
.PaletteEntries
then
682 Colors
:= Info
.PaletteEntries
;
683 for I
:= 0 to Colors
- 1 do
686 Data
.Palette
[I
].A
:= $FF;
687 Data
.Palette
[I
].R
:= palPalEntry
[I
].peRed
;
688 Data
.Palette
[I
].G
:= palPalEntry
[I
].peGreen
;
689 Data
.Palette
[I
].B
:= palPalEntry
[I
].peBlue
;
693 for I
:= 0 to Data
.Height
- 1 do
694 Move(Bitmap
.ScanLine
[I
]^, PByteArray(Data
.Bits
)[I
* LineBytes
], LineBytes
);
696 {$IFDEF COMPONENT_SET_LCL}
697 // Get raw image from bitmap (mask handle must be 0 or expect violations)
698 if RawImage_FromBitmap(RawImage
, Bitmap
.Handle
, 0, nil) then
700 LineLazBytes
:= GetBytesPerLine(Data
.Width
, RawImage
.Description
.BitsPerPixel
,
701 RawImage
.Description
.LineEnd
);
703 for I
:= 0 to Data
.Height
- 1 do
705 Move(PByteArray(RawImage
.Data
)[I
* LineLazBytes
],
706 PByteArray(Data
.Bits
)[I
* LineBytes
], LineBytes
);
708 // May need to swap RB order, depends on wifget set
709 if RawImage
.Description
.BlueShift
> RawImage
.Description
.RedShift
then
710 SwapChannels(Data
, ChannelRed
, ChannelBlue
);
717 procedure ConvertImageToBitmap(Image
: TBaseImage
; Bitmap
: TBitmap
);
719 ConvertDataToBitmap(Image
.ImageDataPointer
^, Bitmap
);
722 procedure ConvertBitmapToImage(Bitmap
: TBitmap
; Image
: TBaseImage
);
724 ConvertBitmapToData(Bitmap
, Image
.ImageDataPointer
^);
728 procedure DisplayImageDataOnDC(DC
: HDC
; const DstRect
: TRect
; const ImageData
: TImageData
; const SrcRect
: TRect
);
731 BitmapInfo
: Windows
.TBitmapInfo
;
734 if TestImage(ImageData
) then
736 Assert(ImageData
.Format
in [ifA8R8G8B8
, ifX8R8G8B8
], SBadFormatDisplay
);
737 OldMode
:= Windows
.SetStretchBltMode(DC
, COLORONCOLOR
);
739 FillChar(BitmapInfo
, SizeOf(BitmapInfo
), 0);
740 with BitmapInfo
.bmiHeader
do
742 biSize
:= SizeOf(TBitmapInfoHeader
);
745 biCompression
:= BI_RGB
;
746 biWidth
:= ImageData
.Width
;
747 biHeight
:= -ImageData
.Height
;
748 biSizeImage
:= ImageData
.Size
;
749 biXPelsPerMeter
:= 0;
750 biYPelsPerMeter
:= 0;
756 with SrcRect
, ImageData
do
757 if Windows
.StretchDIBits(DC
, DstRect
.Left
, DstRect
.Top
,
758 DstRect
.Right
- DstRect
.Left
, DstRect
.Bottom
- DstRect
.Top
, Left
,
759 Top
, Right
- Left
, Bottom
- Top
, Bits
, BitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
) <> Height
then
761 // StretchDIBits may fail on some ocassions (error 487, http://support.microsoft.com/kb/269585).
762 // This fallback is slow but works every time. Thanks to Sergey Galezdinov for the fix.
763 Bmp
:= TBitmap
.Create
;
765 ConvertDataToBitmap(ImageData
, Bmp
);
766 StretchBlt(DC
, DstRect
.Left
, DstRect
.Top
, DstRect
.Right
- DstRect
.Left
, DstRect
.Bottom
- DstRect
.Top
,
767 Bmp
.Canvas
.Handle
, 0, 0, Width
, Height
, SRCCOPY
);
773 Windows
.SetStretchBltMode(DC
, OldMode
);
779 procedure DisplayImageData(DstCanvas
: TCanvas
; const DstRect
: TRect
; const ImageData
: TImageData
; const SrcRect
: TRect
);
780 {$IF Defined(DCC) or Defined(LCLWIN32)} // Delphi or LCL Win32
782 DisplayImageDataOnDC(DstCanvas
.Handle
, DstRect
, ImageData
, SrcRect
);
784 {$ELSEIF Defined(LCLGTK2)}
786 TDeviceContext
= TGtk2DeviceContext
;
788 procedure GDKDrawBitmap(Dest
: HDC
; DstX
, DstY
: Integer; SrcX
, SrcY
,
789 SrcWidth
, SrcHeight
: Integer; ImageData
: TImageData
);
793 P
:= TDeviceContext(Dest
).Offset
;
796 gdk_draw_rgb_32_image(TDeviceContext(Dest
).Drawable
, TDeviceContext(Dest
).GC
,
797 DstX
, DstY
, SrcWidth
, SrcHeight
, GDK_RGB_DITHER_NONE
,
798 @PLongWordArray(ImageData
.Bits
)[SrcY
* ImageData
.Width
+ SrcX
], ImageData
.Width
* 4);
802 DisplayImage
: TImageData
;
803 NewWidth
, NewHeight
: Integer;
804 SrcBounds
, DstBounds
, DstClip
: TRect
;
806 if TestImage(ImageData
) then
808 Assert(ImageData
.Format
in [ifA8R8G8B8
, ifX8R8G8B8
], SBadFormatDisplay
);
809 InitImage(DisplayImage
);
811 SrcBounds
:= RectToBounds(SrcRect
);
812 DstBounds
:= RectToBounds(DstRect
);
813 WidgetSet
.GetClipBox(DstCanvas
.Handle
, @DstClip
);
815 ClipStretchBounds(SrcBounds
.Left
, SrcBounds
.Top
, SrcBounds
.Right
, SrcBounds
.Bottom
,
816 DstBounds
.Left
, DstBounds
.Top
, DstBounds
.Right
, DstBounds
.Bottom
, ImageData
.Width
,
817 ImageData
.Height
, DstClip
);
819 NewWidth
:= DstBounds
.Right
;
820 NewHeight
:= DstBounds
.Bottom
;
822 if (NewWidth
> 0) and (NewHeight
> 0) then
824 if (SrcBounds
.Right
= NewWidth
) and (SrcBounds
.Bottom
= NewHeight
) then
826 CloneImage(ImageData
, DisplayImage
);
827 // Swap R-B channels for GTK display compatability!
828 SwapChannels(DisplayImage
, ChannelRed
, ChannelBlue
);
829 GDKDrawBitmap(DstCanvas
.Handle
, DstBounds
.Left
, DstBounds
.Top
,
830 SrcBounds
.Left
, SrcBounds
.Top
, NewWidth
, NewHeight
, DisplayImage
);
832 FreeImage(DisplayImage
);
836 // Create new image with desired dimensions
837 NewImage(NewWidth
, NewHeight
, ImageData
.Format
, DisplayImage
);
838 // Stretch pixels from old image to new one TResizeFilter = (rfNearest, rfBilinear, rfBicubic);
839 StretchRect(ImageData
, SrcBounds
.Left
, SrcBounds
.Top
, SrcBounds
.Right
,
840 SrcBounds
.Bottom
, DisplayImage
, 0, 0, NewWidth
, NewHeight
, rfNearest
);
841 // Swap R-B channels for GTK display compatability!
842 SwapChannels(DisplayImage
, ChannelRed
, ChannelBlue
);
843 GDKDrawBitmap(DstCanvas
.Handle
, DstBounds
.Left
, DstBounds
.Top
, 0, 0,
844 NewWidth
, NewHeight
, DisplayImage
);
846 FreeImage(DisplayImage
);
853 raise Exception
.Create(SUnsupportedLCLWidgetSet
);
857 procedure DisplayImage(DstCanvas
: TCanvas
; DstX
, DstY
: LongInt; Image
: TBaseImage
);
859 DisplayImageData(DstCanvas
, BoundsToRect(DstX
, DstY
, Image
.Width
, Image
.Height
),
860 Image
.ImageDataPointer
^, Image
.BoundsRect
);
863 procedure DisplayImage(DstCanvas
: TCanvas
; const DstRect
: TRect
; Image
: TBaseImage
);
865 DisplayImageData(DstCanvas
, DstRect
, Image
.ImageDataPointer
^, Image
.BoundsRect
);
868 procedure DisplayImage(DstCanvas
: TCanvas
; const DstRect
: TRect
; Image
: TBaseImage
; const SrcRect
: TRect
);
870 DisplayImageData(DstCanvas
, DstRect
, Image
.ImageDataPointer
^, SrcRect
);
874 { TImagingGraphic class implementation }
876 constructor TImagingGraphic
.Create
;
879 PixelFormat
:= pf24Bit
;
882 procedure TImagingGraphic
.LoadFromStream(Stream
: TStream
);
884 ReadDataFromStream(Stream
);
887 procedure TImagingGraphic
.ReadDataFromStream(Stream
: TStream
);
891 Image
:= TSingleImage
.Create
;
893 Image
.LoadFromStream(Stream
);
900 procedure TImagingGraphic
.AssignTo(Dest
: TPersistent
);
902 Arr
: TDynImageDataArray
;
904 if Dest
is TSingleImage
then
906 AssignToImage(TSingleImage(Dest
))
908 else if Dest
is TMultiImage
then
911 AssignToImageData(Arr
[0]);
912 TMultiImage(Dest
).CreateFromArray(Arr
);
913 Imaging
.FreeImagesInArray(Arr
);
916 inherited AssignTo(Dest
);
919 procedure TImagingGraphic
.Assign(Source
: TPersistent
);
921 if Source
is TBaseImage
then
922 AssignFromImage(TBaseImage(Source
))
924 inherited Assign(Source
);
927 procedure TImagingGraphic
.AssignFromImage(Image
: TBaseImage
);
929 if (Image
<> nil) and Image
.Valid
then
930 AssignFromImageData(Image
.ImageDataPointer
^);
933 procedure TImagingGraphic
.AssignToImage(Image
: TBaseImage
);
935 if (Image
<> nil) and (Image
.ImageDataPointer
<> nil) then
936 AssignToImageData(Image
.ImageDataPointer
^);
939 procedure TImagingGraphic
.AssignFromImageData(const ImageData
: TImageData
);
941 if Imaging
.TestImage(ImageData
) then
942 ConvertDataToBitmap(ImageData
, Self
);
945 procedure TImagingGraphic
.AssignToImageData(var ImageData
: TImageData
);
947 Imaging
.FreeImage(ImageData
);
948 ConvertBitmapToData(Self
, ImageData
);
952 { TImagingGraphicForSave class implementation }
954 constructor TImagingGraphicForSave
.Create
;
957 FDefaultFileExt
:= GetFileFormat
.Extensions
[0];
958 FSavingFormat
:= ifUnknown
;
959 GetFileFormat
.CheckOptionsValidity
;
962 procedure TImagingGraphicForSave
.WriteDataToStream(Stream
: TStream
);
966 if FDefaultFileExt
<> '' then
968 Image
:= TSingleImage
.Create
;
971 if FSavingFormat
<> ifUnknown
then
972 Image
.Format
:= FSavingFormat
;
973 Image
.SaveToStream(FDefaultFileExt
, Stream
);
980 procedure TImagingGraphicForSave
.SaveToStream(Stream
: TStream
);
982 WriteDataToStream(Stream
);
985 {$IFDEF COMPONENT_SET_LCL}
986 class function TImagingGraphicForSave
.GetFileExtensions
: string;
988 Result
:= StringReplace(GetFileFormat
.Extensions
.CommaText
, ',', ';', [rfReplaceAll
]);
991 function TImagingGraphicForSave
.GetMimeType
: string;
993 Result
:= 'image/' + FDefaultFileExt
;
997 {$IFNDEF DONT_LINK_BITMAP}
999 { TImagingBitmap class implementation }
1001 constructor TImagingBitmap
.Create
;
1004 FUseRLE
:= (GetFileFormat
as TBitmapFileFormat
).UseRLE
;
1007 class function TImagingBitmap
.GetFileFormat
: TImageFileFormat
;
1009 Result
:= FindImageFileFormatByClass(TBitmapFileFormat
);
1012 procedure TImagingBitmap
.SaveToStream(Stream
: TStream
);
1014 Imaging
.PushOptions
;
1015 Imaging
.SetOption(ImagingBitmapRLE
, Ord(FUseRLE
));
1016 inherited SaveToStream(Stream
);
1021 {$IFNDEF DONT_LINK_JPEG}
1023 { TImagingJpeg class implementation }
1025 constructor TImagingJpeg
.Create
;
1028 FQuality
:= (GetFileFormat
as TJpegFileFormat
).Quality
;
1029 FProgressive
:= (GetFileFormat
as TJpegFileFormat
).Progressive
;
1032 class function TImagingJpeg
.GetFileFormat
: TImageFileFormat
;
1034 Result
:= FindImageFileFormatByClass(TJpegFileFormat
);
1037 {$IFDEF COMPONENT_SET_LCL}
1038 function TImagingJpeg
.GetMimeType
: string;
1040 Result
:= 'image/jpeg';
1044 procedure TImagingJpeg
.SaveToStream(Stream
: TStream
);
1046 Imaging
.PushOptions
;
1047 Imaging
.SetOption(ImagingJpegQuality
, FQuality
);
1048 Imaging
.SetOption(ImagingJpegProgressive
, Ord(FProgressive
));
1049 inherited SaveToStream(Stream
);
1055 {$IFNDEF DONT_LINK_PNG}
1057 { TImagingPNG class implementation }
1059 constructor TImagingPNG
.Create
;
1062 FPreFilter
:= (GetFileFormat
as TPNGFileFormat
).PreFilter
;
1063 FCompressLevel
:= (GetFileFormat
as TPNGFileFormat
).CompressLevel
;
1066 class function TImagingPNG
.GetFileFormat
: TImageFileFormat
;
1068 Result
:= FindImageFileFormatByClass(TPNGFileFormat
);
1071 procedure TImagingPNG
.SaveToStream(Stream
: TStream
);
1073 Imaging
.PushOptions
;
1074 Imaging
.SetOption(ImagingPNGPreFilter
, FPreFilter
);
1075 Imaging
.SetOption(ImagingPNGCompressLevel
, FCompressLevel
);
1076 inherited SaveToStream(Stream
);
1081 {$IFNDEF DONT_LINK_GIF}
1083 { TImagingGIF class implementation}
1085 class function TImagingGIF
.GetFileFormat
: TImageFileFormat
;
1087 Result
:= FindImageFileFormatByClass(TGIFFileFormat
);
1092 {$IFNDEF DONT_LINK_TARGA}
1094 { TImagingTarga class implementation }
1096 constructor TImagingTarga
.Create
;
1099 FUseRLE
:= (GetFileFormat
as TTargaFileFormat
).UseRLE
;
1102 class function TImagingTarga
.GetFileFormat
: TImageFileFormat
;
1104 Result
:= FindImageFileFormatByClass(TTargaFileFormat
);
1107 procedure TImagingTarga
.SaveToStream(Stream
: TStream
);
1109 Imaging
.PushOptions
;
1110 Imaging
.SetOption(ImagingTargaRLE
, Ord(FUseRLE
));
1111 inherited SaveToStream(Stream
);
1116 {$IFNDEF DONT_LINK_DDS}
1118 { TImagingDDS class implementation }
1120 constructor TImagingDDS
.Create
;
1123 FCompression
:= dcNone
;
1126 class function TImagingDDS
.GetFileFormat
: TImageFileFormat
;
1128 Result
:= FindImageFileFormatByClass(TDDSFileFormat
);
1131 procedure TImagingDDS
.SaveToStream(Stream
: TStream
);
1133 case FCompression
of
1134 dcNone
: FSavingFormat
:= ifUnknown
;
1135 dcDXT1
: FSavingFormat
:= ifDXT1
;
1136 dcDXT3
: FSavingFormat
:= ifDXT3
;
1137 dcDXT5
: FSavingFormat
:= ifDXT5
;
1139 Imaging
.PushOptions
;
1140 Imaging
.SetOption(ImagingDDSSaveCubeMap
, Ord(False));
1141 Imaging
.SetOption(ImagingDDSSaveVolume
, Ord(False));
1142 Imaging
.SetOption(ImagingDDSSaveMipMapCount
, 1);
1143 Imaging
.SetOption(ImagingDDSSaveDepth
, 1);
1144 inherited SaveToStream(Stream
);
1149 {$IFNDEF DONT_LINK_MNG}
1151 { TImagingMNG class implementation }
1153 constructor TImagingMNG
.Create
;
1156 FLossyCompression
:= (GetFileFormat
as TMNGFileFormat
).LossyCompression
;
1157 FLossyAlpha
:= (GetFileFormat
as TMNGFileFormat
).LossyAlpha
;
1158 FPreFilter
:= (GetFileFormat
as TMNGFileFormat
).PreFilter
;
1159 FCompressLevel
:= (GetFileFormat
as TMNGFileFormat
).CompressLevel
;
1160 FQuality
:= (GetFileFormat
as TMNGFileFormat
).Quality
;
1161 FProgressive
:= (GetFileFormat
as TMNGFileFormat
).Progressive
;
1164 class function TImagingMNG
.GetFileFormat
: TImageFileFormat
;
1166 Result
:= FindImageFileFormatByClass(TMNGFileFormat
);
1169 {$IFDEF COMPONENT_SET_LCL}
1170 function TImagingMNG
.GetMimeType
: string;
1172 Result
:= 'video/mng';
1176 procedure TImagingMNG
.SaveToStream(Stream
: TStream
);
1178 Imaging
.PushOptions
;
1179 Imaging
.SetOption(ImagingMNGLossyCompression
, Ord(FLossyCompression
));
1180 Imaging
.SetOption(ImagingMNGLossyAlpha
, Ord(FLossyAlpha
));
1181 Imaging
.SetOption(ImagingMNGPreFilter
, FPreFilter
);
1182 Imaging
.SetOption(ImagingMNGCompressLevel
, FCompressLevel
);
1183 Imaging
.SetOption(ImagingMNGQuality
, FQuality
);
1184 Imaging
.SetOption(ImagingMNGProgressive
, Ord(FProgressive
));
1185 inherited SaveToStream(Stream
);
1190 {$IFNDEF DONT_LINK_JNG}
1192 { TImagingJNG class implementation }
1194 constructor TImagingJNG
.Create
;
1197 FLossyAlpha
:= (GetFileFormat
as TJNGFileFormat
).LossyAlpha
;
1198 FAlphaPreFilter
:= (GetFileFormat
as TJNGFileFormat
).PreFilter
;
1199 FAlphaCompressLevel
:= (GetFileFormat
as TJNGFileFormat
).CompressLevel
;
1200 FQuality
:= (GetFileFormat
as TJNGFileFormat
).Quality
;
1201 FProgressive
:= (GetFileFormat
as TJNGFileFormat
).Progressive
;
1204 class function TImagingJNG
.GetFileFormat
: TImageFileFormat
;
1206 Result
:= FindImageFileFormatByClass(TJNGFileFormat
);
1209 procedure TImagingJNG
.SaveToStream(Stream
: TStream
);
1211 Imaging
.PushOptions
;
1212 Imaging
.SetOption(ImagingJNGLossyALpha
, Ord(FLossyAlpha
));
1213 Imaging
.SetOption(ImagingJNGAlphaPreFilter
, FAlphaPreFilter
);
1214 Imaging
.SetOption(ImagingJNGAlphaCompressLevel
, FAlphaCompressLevel
);
1215 Imaging
.SetOption(ImagingJNGQuality
, FQuality
);
1216 Imaging
.SetOption(ImagingJNGProgressive
, Ord(FProgressive
));
1217 inherited SaveToStream(Stream
);
1227 {$IFEND} // {$IF not Defined(COMPONENT_SET_LCL) and not Defined(COMPONENT_SET_VCL)}
1232 -- TODOS ----------------------------------------------------
1235 -- 0.77.1 ---------------------------------------------------
1236 - Fixed bug in ConvertBitmapToData causing images from GTK2 bitmaps
1237 to have swapped RB channels.
1238 - LCL: Removed GTK1 support (deprecated).
1240 -- 0.26.3 Changes/Bug Fixes ---------------------------------
1241 - Transparency of 8bit images (like loaded from 8bit PNG or GIF) is
1242 kept intact during conversion to TBitmap in ConvertDataToBitmap
1243 (32bit bitmap is created).
1245 -- 0.26.3 Changes/Bug Fixes ---------------------------------
1246 - Setting AlphaFormat property of TBitmap in ConvertDataToBitmap
1247 when using Delphi 2009+.
1248 - Fixed garbled LCL TBitmaps created by ConvertDataToBitmap
1249 in Mac OS X (Carbon).
1251 -- 0.26.1 Changes/Bug Fixes ---------------------------------
1252 - Added some more IFDEFs for Lazarus widget sets.
1254 - GTK version of Unix DisplayImageData only used with LCL GTK so the
1255 the rest of the unit can be used with Qt or other LCL interfaces.
1256 - Fallback mechanism for DisplayImageDataOnDC, it may fail on occasions.
1257 - Changed file format conditional compilation to reflect changes
1259 - Lazarus 0.9.26 compatibility changes.
1261 -- 0.24.1 Changes/Bug Fixes ---------------------------------
1262 - Fixed wrong IFDEF causing that Imaging wouldn't compile in Lazarus
1264 - Added commnets with code for Lazarus rev. 11861+ regarding
1265 RawImage interface. Replace current code with that in comments
1266 if you use Lazarus from SVN. New RawImage interface will be used by
1267 default after next Lazarus release.
1269 -- 0.23 Changes/Bug Fixes -----------------------------------
1270 - Added TImagingGIF.
1272 -- 0.21 Changes/Bug Fixes -----------------------------------
1273 - Uses only high level interface now (except for saving options).
1274 - Slightly changed class hierarchy. TImagingGraphic is now only for loading
1275 and base class for savers is new TImagingGraphicForSave. Also
1276 TImagingGraphic is now registered with all supported file formats
1277 by TPicture's format support.
1279 -- 0.19 Changes/Bug Fixes -----------------------------------
1280 - added DisplayImage procedures (thanks to Paul Michell, modified)
1281 - removed RegisterTypes and UnRegisterTypes from interface section,
1282 they are called automatically
1283 - added procedures: ConvertImageToBitmap and ConvertBitmapToImage
1285 -- 0.17 Changes/Bug Fixes -----------------------------------
1286 - LCL data to bitmap conversion didn“t work in Linux, fixed
1287 - added MNG file format
1288 - added JNG file format
1290 -- 0.15 Changes/Bug Fixes -----------------------------------
1291 - made it LCL compatible
1292 - made it CLX compatible
1293 - added all initial stuff