Menu

#22 BMP & GIF problem

1.0
closed
nobody
None
2022-03-18
2022-03-17
No

Hello,

Please note that when exporting () to GIF an access violation is raised:

procedure TImageFormat_GIF.SaveToStream(stream: TStream; img32: TImage32);
var
  gif: TGIFImage;
begin
  gif := TGIFImage.Create;
  with gif.Bitmap do
  try
    Width := img32.Width;
    Height := img32.Height;
    if GetCurrentThreadId <> MainThreadID then Canvas.Lock;
    try
      img32.CopyToDc(gif.Bitmap.Canvas.Handle,0,0, false);
    finally
      if GetCurrentThreadId <> MainThreadID then Canvas.Unlock;
    end;
    gif.SaveToStream(stream);
  finally
    gif.Free;
  end;
end;

After TGIFImage creation, the property of Bitmap is set to nil which caused the AV.

When saving to Bitmap using SaveToStream(Stream,'bmp'), the output is not Bitmap compatible and it seams that the header is missed.

Best regards.

Discussion

  • Angus Johnson

    Angus Johnson - 2022-03-17

    Hi Hafedh.
    Thanks for the feedback, and I've verified that that this is indeed a bug.

    Hopefully this will work ...

    procedure TImageFormat_GIF.SaveToStream(stream: TStream; img32: TImage32);
    var
      gif: TGIFImage;
      bmp: TBitmap;
    begin
      bmp := TBitmap.Create;
      gif := TGIFImage.Create;
      try
        //copy to the new TBitmap
        bmp.PixelFormat := pf32bit;
        bmp.SetSize(img32.Width, img32.Height);
        bmp.AlphaFormat := afDefined;
        SetBitmapBits(bmp.Handle,
          img32.Width * img32.Height * 4, img32.PixelBase);
        //next copy from the bitmap to the new TGifImage
        gif.Add(bmp);
        //and now save
        gif.SaveToStream(stream);
      finally
        gif.Free;
        bmp.Free;
      end;
    end;
    
     
  • Angus Johnson

    Angus Johnson - 2022-03-18
    • status: open --> closed
     
    • Hafedh TRIMECHE

      Hafedh TRIMECHE - 2022-03-18

      Dear Jhonson,

      Thank you for your prompt response.

      The Bitmap still exported without BMP File Header.

      This function would resolve the problem:

      function TImage32.ToBitmap:TBitmap;
      begin
        Result             := TBitmap.Create;
        Result.Width       := Width;
        Result.Height      := Width;
        Result.PixelFormat := pf24bit;
        CopyToDc(Result.Canvas.Handle);
      end;
      

      Best regards.

       
  • Angus Johnson

    Angus Johnson - 2022-03-18

    Sorry, I missed your earlier comment re BMP file headers.

    Yes TImageFormat_BMP.SaveToStream intentionally omits the file header because they are only required when saving to file streams, and the TImageFormat_BMP.SaveToFile function does include the file header. However, when saving to other streams, eg BMP resource streams, the file header is not required and can cause problems. If you really need the file header in a 'non-file' stream, then you'll need to manually copy the header into the stream before the image (just as is done in TImageFormat_BMP.SaveToFile).