Mega Code Archive

 
Categories / Delphi / ADO Database
 

Easy and Simple way Using ADO with any image in MS Access with EDBImage

Title: Easy and Simple way Using ADO with any image in MS Access with EDBImage Question: I got an error message bitmap image is not valid. I try several tips out there, but none of them works. From several tips I found, this is my simple solution: Answer: Why this happen? watch this blob file viewed in hex editor : 1 151C2F00020000000D000E0014002100 ../...........!. 2 FFFFFFFF4269746D617020496D616765 ....Bitmap Image 3 005061696E742E506963747572650001 .Paint.Picture.. 4 05000002000000070000005042727573 ...........PBrus 5 6800000000000000000020540000424D h......... T..BM 6 16540000000000007600000028000000 .T......v...(... 7 C0000000DF0000000100040000000000 ................ 8 A0530000CE0E0000D80E000000000000 .S.............. MS Access stores some information (for JPEG or other type it also include the path of a linked OLE) in object as part of the object's definition in the OLE object field. Because the definition of OLE object storage is not documented (!? this is straight from MS) there is no way to know what gets written before the actual image data. Obviously line 2 says the data stream is a "Bitmap Image." I assume in Lines 4-5 that PBrush ("Paintbrush") is the program that should be used to open the file. The first two bytes of BMP files normally are "BM" or 42 4D in hex, so that it appears that the BMP file starts in line 5, at byte 14 above -- byte 78 within the file. Download EDBImage in here (http://delphi.icm.edu.pl/) EDBImage works like TDBImage except : - It can manage .ico .bmp .wmf .emf .jpg .jpeg. Without a line of code !!! - Can copy to clipboard .bmp .wmf .jpg .jpeg - Event OnLoadCustomImage is fired when the image type is unknown, so you can load "any" type of images (gif, tiff, png,....). Because Bitmap is always start in byte 78 within the BLOB, you can use the OnLoadCustomImage in this way: procedure TForm1.EDBImage1LoadCustomImage(var B: TGraphic; Stream: TStream); begin B := TBitmap.Create; Stream.Seek(78, soFromBeginning); B.LoadFromStream(Stream); end; --------------------------------------------------------------------------- JPEG start with FF D8. But not always be at the same position in the file. Well need to seek to the 'FFD8' and read the image from there. You can use this function: function JpegStartsInBlob (Stream : TStream):integer; var buffer : Word; hx : string; begin Result := -1; while (Result = -1) and (Stream.Position + 1 begin Stream.ReadBuffer(buffer, 1); hx:=IntToHex(buffer, 2); if hx = 'FF' then begin Stream.ReadBuffer(buffer, 1); hx:=IntToHex(buffer, 2); if hx = 'D8' then Result := Stream.Position - 2 else if hx = 'FF' then Stream.Position := Stream.Position-1; end; //if end; //while end; procedure TForm1.EDBImage1LoadCustomImage(var B: TGraphic; Stream: TStream); begin B := TJPEGImage.Create; Stream.Seek(JpegStartsInBlob (Stream), soFromBeginning); B.LoadFromStream(Stream); end; That is ALL.!!! - do not call B.Free. You can use any image, since you have the library that support the image. For many graphic support you can use GraphicEx library from Mike Lischke (www.soft-gems.net) . And use hex editor to see the header. e.g. : 42 4D : Bitmap 4D 4D : TIFF 47 49 : GIF D7 CD : Metafile FF D8 : JPEG I try to create function that support JPEG and Bitmap, the JPEG is ok but its only support Bitmap in 16 bit. So if anyone knows how to fix that or to optimize the code, please post here.