Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access TBitmap pixels directly in FMX2 (TBitmap.ScanLine replacement)?

The FMX.Types.TBitmap class has the ScanLine property in FMX (FireMonkey), but it seems this property was removed, and is missing in FMX2 (FireMonkey FM2).

Is there any workaround ? How do we supposed to access TBitmap content directly in FMX2 ?

like image 726
Roman Yankovsky Avatar asked Feb 17 '23 08:02

Roman Yankovsky


2 Answers

For direct access you are expect to use the Map method. The documentation includes a number of examples, such as FMX.AlphaColorToScanline:

function TForm1.TestAlphaColorToScanline(ABitmap: TBitmap;
  start, count: integer): TBitmap;
var
  bitdata1, bitdata2: TBitmapData;
begin
  Result := TBitmap.Create(Round(ABitmap.Width), Round(count));
  if (ABitmap.Map(TMapAccess.maRead, bitdata1) and
    Result.Map(TMapAccess.maWrite, bitdata2)) then
  begin
    try
      AlphaColorToScanline(@PAlphaColorArray(bitdata1.Data)
        [start * (bitdata1.Pitch div GetPixelFormatBytes(ABitmap.PixelFormat))],
        bitdata2.Data, Round(Result.Height * Result.Width),
        ABitmap.PixelFormat);
    finally
      ABitmap.Unmap(bitdata1);
      Result.Unmap(bitdata2);
    end;
  end;
end;
like image 77
David Heffernan Avatar answered May 11 '23 17:05

David Heffernan


Here is an example for C++Builder (the current docs are completely missing such):

int X, Y;
TBitmapData bm;

// get bitmap data access !
if ( Image1->Bitmap->Map(TMapAccess::maReadWrite, bm) )
{
    unsigned int* data = (unsigned int*)bm.Data;

    // i.e. clear data with alpha color
    memset(data, 0,
    Image1->Width * Image1->Height * sizeof(unsigned int));

    // test direct pixel access here
    for (X = 20; X <= 200; X++)
    {
        for (Y = 10; Y <= 100; Y++)
        {
            //MyBitmap->Pixels[X][Y] = claLime;  // does not work anymore !
            bm.SetPixel(X, Y, claLime);
        }
    }

    // now write back the result !
    Image1->Bitmap->Unmap(bm);
}
else
{
    MessageDlg("Could not map the image data for direct access.",
    TMsgDlgType::mtWarning, TMsgDlgButtons() << TMsgDlgBtn::mbOK, 0);
}
like image 21
Jason Avatar answered May 11 '23 16:05

Jason