Erwin,

Thanks again for your help. I managed to get the scanline process to work
using your examples below, but had to resort to a slightly slower pixel by
pixel approach due to the fact that the order the bytes were coming in
ImageData was actually BGR which differed to the RGB byte order expected by
the TIFF image (hence blue was red in the final image). The only way I could
fix it was to apply a manual fix as I wrote the pixels to the destination
scanline one by one.

Thanks for the help though. I have learned a lot.

Kind regards,
Darren

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf
Of Erwin Haid
Sent: 06 April 2005 01:02
To: Borland's Delphi Discussion List
Subject: RE: Working with bitmaps

Hi Darren,

copying a bitmap line by line is the same for monochrome and for color
bitmaps.

First you have to calculate the size of a line in bytes

  LineSize = Width * 3; // 3 bytes per pixel for pixelformat pf24bit

then you have to calculate the pitch (linesize aligned by 2 bytes)

  Pitch = AlignWord(LineSize);

you can calculate the source pointer for scanline y

  pSrc = pImageDataSrc + y * Pitch

the destination pointer is the scanline of the bitmap

  pDst = bmpDest.Scanline[y];

then you can copy the whole scanline

  CopyMemory(pDst,pSrc,LineSize);


Here is a small example you can play with, just create a new application in
delphi and drop an image and a button on the form:

----------------------------------------------------------

function AlignWord(const x: Integer): Integer; begin
   Result := (x + 1) and not 1;
end;

procedure WriteToColourBitmap(dstBitmap: TBitmap; const ImageData: PChar;
const Width, Height: Integer); var
  y, pitch, linesize: Integer;
  pSrcScanline,pDstScanline: PChar;
begin
  linesize := Width * 3; // 3 bytes per pixel for pf24bit
  pitch := AlignWord(linesize);

  for y := 0 to Height-1 do
  begin
    pSrcScanline := ImageData + y * pitch;
    pDstScanline := dstBitmap.Scanline[y];

    CopyMemory(pDstScanline,pSrcScanline,linesize);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject); const
  IMG_WIDTH = 543;
  IMG_HEIGHT = 345;
  BYTES_PER_PIXEL = 3; // 24 bit image
  LINE_SIZE = IMG_WIDTH * BYTES_PER_PIXEL; // size of line in bytes
  LINE_PITCH = (LINE_SIZE + 1) and not 1; // 2-byte aligned var
  ImageData: array[0..IMG_HEIGHT*LINE_PITCH-1] of byte;
  x,y: Integer;
  bmp: TBitmap;
begin
  // fill buffer with some image data
  FillMemory(@ImageData[0],SizeOf(ImageData),0);
  for y := 0 to IMG_HEIGHT-1 do
  begin
    for x := 0 to IMG_WIDTH-1 do
    begin
      with PRGBTriple(@ImageData[y*LINE_PITCH+x*BYTES_PER_PIXEL])^ do
      begin
        rgbtBlue  := Byte(x and not 15);
        rgbtGreen := Byte(y and not 15);
        rgbtRed   := Byte(rgbtBlue+rgbtGreen);
      end;
    end;
  end;

  // Write ImageData to bitmap
  bmp := TBitmap.Create;
  try
    bmp.Width := IMG_WIDTH;
    bmp.Height := IMG_HEIGHT;
    bmp.PixelFormat := pf24Bit;

    WriteToColourBitmap(bmp,PChar(@ImageData[0]),IMG_WIDTH,IMG_HEIGHT);

    Image1.Picture.Bitmap.Assign(bmp);
  finally
     bmp.Free;
  end;
end;



_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to