0

Can I convert TBitmap32 object to TBitmap (pf32bit) object without copying pixels?

I found 2 methods to copy TBitmap32 to TBitmap without visibly copying pixels but maybe there are pixels being copied under the hood. Or maybe one method is better somehow than another? Could someone knowing WinAPI advise?

var bmp2: TBitmap32;
    bmp: TBitmap;

    h: HBitmap;
    tag: tagBITMAP;
begin
  bmp2 := TBitmap32.Create;
  bmp2.LoadFromFile('in.bmp');


  tag.bmType := 0;
  tag.bmWidth := bmp2.Width;
  tag.bmheight := bmp2.height;
  tag.bmWidthBytes := bmp2.Width*4;
  tag.bmPlanes := 1;
  tag.bmBitsPixel := 32;
  tag.bmBits := @bmp2.Bits[0];

  h := CreateBitmapIndirect(tag);

  bmp := TBitmap.Create;
  bmp.PixelFormat := pf32bit;
  bmp.Handle := h;


  bmp.SaveToFile('out.bmp');

Method 2

var bmp2: TBitmap32;
    bmp: TBitmap;
    x,y: Integer;

    h: HBitmap;
    bi  : TBitmapInfo;
    res : integer;
    abitmap: HBitmap;
begin
  bmp2 := TBitmap32.Create;
  bmp2.LoadFromFile('in.bmp');


  FillChar (bi,SizeOf(bi),0);
  with bi.bmiHeader do
  begin
     biSize := SizeOf(bi.bmiHeader);
     biWidth := bmp2.Width;
     biHeight := bmp2.height;
     biPlanes := 1;
     biBitCount := 32;
     biCompression := BI_RGB;
  end;

  bmp := TBitmap.Create;

  aBitmap := 0;
  try
    aBitmap := CreateDIBitmap(GetDC(0), bi.bmiHeader, CBM_INIT,  @bmp2.Bits[0], bi, DIB_RGB_COLORS);
    bmp.handle := aBitmap;
    bmp.SaveToFile('out.bmp');
  finally
    DeleteObject(aBitmap);
    bmp.Free;
  end;
Tom
  • 2,962
  • 3
  • 39
  • 69
  • What's wrong with `TBitmap32.AssignTo`? It doesn't require any WinAPI calls in your code, and no jumping through hoops. – Ken White Jun 21 '19 at 16:49
  • @KenWhite It seems it's copying pixels and my bitmaps are huge. – Tom Jun 21 '19 at 17:02
  • You need to copy pixels. – David Heffernan Jun 21 '19 at 17:55
  • I thought your question was about *manually having to copy pixels in your code*. How do you expect to be able to copy the bitmap without copying pixels? You're making a **copy** from TBitmap32 to TBitmap. – Ken White Jun 21 '19 at 17:55
  • @KenWhite The pixels are already in the same format in RAM. I thought it can be done with pointers. – Tom Jun 21 '19 at 19:38
  • 1
    You're asking if you can move a pointer from one object to another object that is not identical, and the answer is no. If the objects were that exact, there would be no conversion necessary. – Ken White Jun 21 '19 at 19:39
  • 1
    @KenWhite To be fair, it is not inconceivable that objects could be designed to work on a buffer that is provided by the user. I've seen that done. It just isn't an option here. – David Heffernan Jun 21 '19 at 20:23
  • @DavidHeffernan: And as usual, my comment was meant to be in the context of this particular question, and not a general statement, and most people would interpret it in that context. – Ken White Jun 22 '19 at 01:37
  • @Ken It's always hard to read between the lines, especially in short written comments. Perhaps what you meant to say is that a GDI bitmap cannot operate with an external pixel buffer. – David Heffernan Jun 22 '19 at 07:42
  • @KenWhite , DavidHeffernan Thank you for your answers. I hoped that because CreateDIBitmap accepts a pointer to pixels it just uses that buffer. – Tom Jun 22 '19 at 09:20

0 Answers0