Hi to all !,
I am trying to read a 24 bpp (or 32 bpp) bitmap from hard disk, because I am
trying to implement a bitmap reader that will read the bitmap in chunks
(without using a TBitmap) because I have very large bitmaps and the target
machine will not have enough memory and Windows 98 have some problems with
big bitmaps. Bitmap is assumed to be uncompressed also.
With the following code, I successful can read the bitmap and display on a
form. The problem is that some stain (or marks) appears on the bitmap.
Do you know what is happening ?
You can test this very easily by copying and pasting to a TButton.OnClick
event on an empty form, and changing following line for reading your own
bitmaps:
FileName:= 'c:\MyBitmaps\Data\TestBitmap.bmp';
procedure TForm1.Button1Click(Sender: TObject);
var
FileName: string;
Stream: TStream;
TheHeaderSize: Integer;
bmf: TBITMAPFILEHEADER;
BitmapInfo: PBitmapInfo;
bmWidth: Integer;
bmHeight: Integer;
BytesPerScanLine: Integer;
Bits: Pointer;
begin
FileName:= 'c:\MyBitmaps\Data\TestBitmap.bmp';
Stream:= TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
Stream.ReadBuffer(bmf, sizeof(TBITMAPFILEHEADER));
TheHeaderSize := bmf.bfOffBits - sizeof(TBITMAPFILEHEADER);
BitmapInfo := Pointer(GlobalAlloc(GPTR,TheHeaderSize));
try
Stream.ReadBuffer(BitmapInfo^, TheHeaderSize);
{ check for uncompressed only and >= 24 bpp }
if ((BitmapInfo^.bmiHeader.biCompression = BI_RLE4) or
(BitmapInfo^.bmiHeader.biCompression = BI_RLE8)) or
(BitmapInfo^.bmiHeader.biBitCount < 24) then
begin
exit;
end;
bmWidth := BitmapInfo^.bmiHeader.biWidth;
bmHeight := abs(BitmapInfo^.bmiHeader.biHeight);
BytesPerScanLine :=((((bmWidth * BitmapInfo^.bmiHeader.biBitCount) +
31) and not 31) div 8);
Bits := Pointer(GlobalAlloc(GPTR, BytesPerScanLine * bmHeight));
try
// read the full bitmap bits
Stream.seek(bmf.bfOffBits, soFromBeginning);
Stream.ReadBuffer(Bits^, BytesPerScanLine * bmHeight);
{ now draw to the form }
StretchDIBits(
self.Canvas.Handle,
0,
0,
self.ClientWidth-1,
self.ClientHeight-1,
0,
0,
bmWidth-1,
bmHeight-1,
Bits,
BitmapInfo^,
DIB_RGB_COLORS,
SRCCOPY );
finally
GlobalFree(THandle(Bits));
end;
finally
GlobalFree(THandle(BitmapInfo));
end;
finally
Stream.Free;
end;
end;
Thanks for any help.
Regards
Alex