Board index » delphi » Reading bitmap from disk without using TBitmap

Reading bitmap from disk without using TBitmap

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

 

Re:Reading bitmap from disk without using TBitmap


"Alex S" <graph_developm...@yahoo.com> skrev i en meddelelse
news:3c578512$1_2@dnews...

Quote
> 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 ?
>         { now draw to the form }
>         StretchDIBits(

Just before this line, issue this command:
      SetStretchBltMode(Self.Canvas.Handle, COLORONCOLOR);
The problem is that you are stretching the bitmap. The stretching is what
causes the stains.
The COLORONCOLOR value is good for color/photo images.
For other kind of images, other values may give better results.
Look in the win32 help for an explanation.
--
Finn Tolderlund

Re:Reading bitmap from disk without using TBitmap


Thank you very much !.
It worked perfectly

Other Threads