TBitmap32.LoadFromStream () Automatically recognize image format

I am using Delphi XE2 (Update 3) and GR32. I cannot use TBitmap32.LoadFromStream() to load image data. This throws the following exception:

 Project MyApp.exe raised exception class EInvalidGraphic with message 'Bitmap image is not valid'. 

code

 uses GR32, GifImg, PngImage, Vcl.Graphics; var pic: TBitmap32; bs: TBytesStream; begin bs := TBytesStream.Create(TClientDataSet(cds).FieldByName('filedata').AsBytes); try pic := TBitmap32.Create; try // bs.SaveToFile('c:\delme.png'); // pic.LoadFromFile('c:\delme.png'); pic.LoadFromStream(bs); // <- EInvalidGraphic exception // do something with 'pic' finally FreeAndNil(pic); end; finally FreeAndNil(bs); end; end; 

Bypass (s)

If I comment on the code of LoadFromStream() and uncomment the previous two lines, it works - so it can determine the image format when loading from a file. In this example, bs contains a valid PNG image. However, sometimes it can be GIF, JPG, BMP or another graphic format.

I also know that I can use an intermediate object (e.g. TPNGImage , TJPEGImage , etc.), load image data using LoadFromStream() into the intermediate object, and then Assign() it on TBitmap32 . However, it would be better if TBitmap32 could process any type of image without an intermediate object, which, as I thought, could ...

Question

Does anyone know how to use TBitmap32.LoadFromStream() to load an image and automatically recognize the image format without saving the image to the HDD (even temporarily) or using an intermediate object?

+4
source share
2 answers

This is the code for LoadFromFile :

 procedure TCustomBitmap32.LoadFromFile(const FileName: string); var FileStream: TFileStream; Header: TBmpHeader; P: TPicture; begin FileStream := TFileStream.Create(Filename, fmOpenRead); try FileStream.ReadBuffer(Header, SizeOf(TBmpHeader)); // Check for Windows bitmap magic bytes... if Header.bfType = $4D42 then begin // if it is, use our stream read method... FileStream.Seek(-SizeOf(TBmpHeader), soFromCurrent); LoadFromStream(FileStream); Exit; end finally FileStream.Free; end; // if we got here, use the fallback approach via TPicture... P := TPicture.Create; try P.LoadFromFile(FileName); Assign(P); finally P.Free; end; end; 

As you can see, the code checks if the file is a Windows bitmap. If so, it loads it directly by calling LoadFromStream .

If not, it is loaded into TPicture and then assigned to this instance.

The fact is that LoadFromStream only understands Windows bitmaps. He does not understand another file format. And you are trying to download PNG. Thus, there is no way to do what you need without using an intermediate object.

The solution for you:

  • Create an instance of the TPNGImage object.
  • Call LoadFromStream on this instance.
  • Assign instance of TBitmap32 passing the TPNGImage instance.
+3
source

Delphi XE2 includes a class in Vcl.Graphics called TWICImage , which processes images supported by Windows Imaging , including BMP, GIF, ICO, JPEG, PNG, TIF, and Windows Media Photo . This means that you can load any of the supported image types directly from the stream, and it will automatically detect the type of image and load it. Then, the downloaded image can be assigned to the TBitmap32 component (either TImage or TImage32 , etc.).

 uses GR32, Vcl.Graphics; var pic: TBitmap32; wic: TWICImage; bs: TBytesStream; begin bs := TBytesStream.Create(TClientDataSet(cds).FieldByName('filedata').AsBytes); try pic := TBitmap32.Create; try wic := TWICImage.Create; try bs.Position := 0; wic.LoadFromStream(bs); pic.Assign(wic); finally FreeAndNil(wic); end; finally FreeAndNil(pic); end; finally FreeAndNil(bs); end; end; 

It works without adding PNGImage , GIFImg or JPEG to the uses statement.

+4
source

Source: https://habr.com/ru/post/1487240/


All Articles