Jump to content
dkprojektai

Image pointer and buffer size

Recommended Posts

Hello, need help.

 

How can I find in Delphi pointer to memory buffer which contain image file data and size of memory buffer in bytes ?

 

These are not correct:

@Bitmap1

Bitmap1.ScanLine[0]

 

Buffer size can be found:

function GetGraphicSize(g: TGraphic): Integer;
var
  ms: TStream;
begin
  ms := TMemoryStream.Create;
  try
    g.SaveToStream(ms);
    Result := ms.Size;
  finally
    ms.Free;
  end;
end;

 

How can do it correctly ?

 

 

 

Share this post


Link to post

Bitmap1.ScanLine[Bitmap1.Height-1] is start of the image buffer (raw image data, it is bottom up).

Buffer size is not so easy; in VCL.Graphics, they have this function (Alignment=32; you need to multiply its result by Bitmap1.Height; look at TBitmap.GetScanLine in VCL.Graphics).

function BytesPerScanline(PixelsPerScanline, BitsPerPixel, Alignment: Longint): Longint;
begin
  Dec(Alignment);
  Result := ((PixelsPerScanline * BitsPerPixel) + Alignment) and not Alignment;
  Result := Result div 8;
end;

 

Share this post


Link to post

Do you need pointer to raw image data (say RGB bytes for 24 bit/px images - ScanLine), or pointer to data which you saved to ms in your example? tMemoryStream has property Memory (pointer to its data).

Share this post


Link to post

I have Tbitmap

 

I need:

*    pBuffer - Pointer to memory buffer which contain image file data
*    bufferSize - size of memory buffer in bytes

Share this post


Link to post
3 hours ago, dkprojektai said:

pBuffer - Pointer to memory buffer which contain image file data

You didn't really answer @Vandrovnik's question.

 

For Windows bitmaps the bitmap file image (i.e. bitmap header and pixel data) isn't stored in memory.

When TBitmap loads a bmp file it reads the header information then the pixel data. From this it stores the relevant meta data (width/height, color depth, palette, etc) and pixel data in memory.

Of these you only have direct access to the raw pixel data.

 

If you need the file bitmap image in memory then you will either have to save the bitmap to a memory stream or construct the image yourself in memory.

 

btw, when I write "image" I don't mean in the picture/graphic/bitmap sense.

 

Maybe you should try to explain what problem you are trying to solve.

  • Like 1

Share this post


Link to post

What is your actual problem for which you need a solution? Because what you are asking doesn't actually make sense. 

  • Like 1

Share this post


Link to post

I have Bitmap and want to pass it this function

 

function ReadFromMemFile(hEngine: TENGINE; pBuffer: Pointer; bufferSize: Integer): TRESULT;

Share this post


Link to post
2 hours ago, dkprojektai said:

function ReadFromMemFile(hEngine: TENGINE; pBuffer: Pointer; bufferSize: Integer): TRESULT;

You're not giving us much to work with here.

Do you have any documentation about what kind of data ReadFromMemFile expect the input buffer to hold?

Share this post


Link to post

Perhaps you know what this is. 

2 hours ago, dkprojektai said:

function ReadFromMemFile(hEngine: TENGINE; pBuffer: Pointer; bufferSize: Integer😞 TRESULT;

We don't. 

 

Try to imagine that we can't see your screen. 

  • Like 1

Share this post


Link to post
8 hours ago, Vandrovnik said:

Bitmap1.ScanLine[Bitmap1.Height-1] is start of the image buffer (raw image data, it is bottom up).

The TBitmap.ScanLine property getter handles top-down vs bottom-up differences for you.  You can use scanline indexes as if the bitmap were always top-down, like a normal array, and the property getter will access the raw pixels as needed based on whether the bitmap is top-down or bottom-up.  In other words, ScanLine[0] always represents the 1st line of pixels, ScanLine[1] always represents the 2nd line of pixels, and so on.

function TBitmap.GetScanLine(Row: Integer): Pointer;
begin
  Changing(Self);
  with FImage.FDIB, dsbm, dsbmih do
  begin
    if (Row < 0) or (Row >= bmHeight) then
      InvalidOperation(@SScanLine);
    DIBNeeded;
    GDIFlush;
    if biHeight > 0 then  // bottom-up DIB
      Row := biHeight - Row - 1;
    Result := PByte(bmBits) +
      Row * BytesPerScanline(biWidth, biBitCount, 32);
  end;
end;

That means if you want a raw pointer to the entire image buffer as a whole, then you have to use ScanLine[0] for a top-down bitmap, and ScanLine[Height-1] for a bottom-up bitmap.  But, if you just want to access the individual lines one at a time, then you can loop through ScanLine[0]..ScanLine[Height-1] without regard to whether the bitmap is top-down or bottom-up.

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post
4 hours ago, dkprojektai said:

I have Bitmap and want to pass it this function

 

function ReadFromMemFile(hEngine: TENGINE; pBuffer: Pointer; bufferSize: Integer): TRESULT;

Without knowing exactly what that function actually is or where it comes from, and given how few parameters it takes, it MOST LIKELY is expecting the WHOLE bitmap, header and everything, not just the raw pixel data by itself.  If so, you would just have to load your BMP file or TBitmap object into a TMemoryStream first, and then you can pass its Memory and Size properties to that function's parameters, eg:

 

MS := TMemoryStream.Create;
try
  MS.LoadFromFile('image.bmp');
  or
  BmpObj.SaveToStream(MS);

  Result := ReadFromMemFile(hEngine, MS.Memory, MS.Size);
finally
  MS.Free;
end;

 

Edited by Remy Lebeau
  • Like 2

Share this post


Link to post
12 hours ago, Remy Lebeau said:

Without knowing exactly what that function actually is or where it comes from, and given how few parameters it takes, it MOST LIKELY is expecting the WHOLE bitmap, header and everything, not just the raw pixel data by itself.  If so, you would just have to load your BMP file or TBitmap object into a TMemoryStream first, and then you can pass its Memory and Size properties to that function's parameters, eg:

 


MS := TMemoryStream.Create;
try
  MS.LoadFromFile('image.bmp');
  or
  BmpObj.SaveToStream(MS);

  Result := ReadFromMemFile(hEngine, MS.Memory, MS.Size);
finally
  MS.Free;
end;

 

That is what I wanted and it helped. Thanks Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×