I’m working with a developer to build a component and one of the issues we ran into is that when you take a screenshot of a set of controls with Delphi XE5 Firemonkey and then put it into a TImage control Firemonkey applies an antialias to the image. This is mainly an issue around text. Since we were looking for a pixel perfect representation of the controls as a bitmap I looked for some way to help remove the antialias effect from the bitmap. The background of the controls is transparent so one idea I came up with was to change all of the partially transparent pixels below a certain threshold to fully transparent. On the Embarcadero site I found this TestAlphaColorToPixel() function which shows changing every third line to solid red. I modified this function to read each pixel, check it’s opacity, and if it is below the opacity threshold change it to completely transparent. It does not completely solve the antialiasing problem but it helps slightly. You can take this function and modify it to suit your own needs for modifying all of the pixels in a bitmap. TAlphaColorRec has four properties you can use for this which are A for alpha, R for red, B for blue, and G for green. This function should work on Android, IOS, Windows, and OSX. You can take a look at the other PixelFormat functions including scanline access using ScanLineToAlphaColor.
procedure ApplyNoAlphaEdge(ABitmap: TBitmap; OpacityThreshold: integer);
var
bitdata1: TBitmapData;
I: integer;
J: integer;
C: TAlphaColor;
begin
if (ABitmap.Map(TMapAccess.maReadWrite, bitdata1)) then
try
for I := 0 to ABitmap.Width - 1 do
for J := 0 to ABitmap.Height - 1 do
begin
begin
C := PixelToAlphaColor(@PAlphaColorArray(bitdata1.Data)
[J * (bitdata1.Pitch div GetPixelFormatBytes(ABitmap.PixelFormat))
+ 1 * I], ABitmap.PixelFormat);
if TAlphaColorRec(C).A<OpacityThreshold then
begin
TAlphaColorRec(C).A := 0;
AlphaColorToPixel(C, @PAlphaColorArray(bitdata1.Data)
[J * (bitdata1.Pitch div GetPixelFormatBytes(ABitmap.PixelFormat))
+ 1 * I], ABitmap.PixelFormat);
end;
end;
end;
finally
ABitmap.Unmap(bitdata1);
end;
end;
If you know of a way to have Firemonkey not automatically antialias bitmaps or a better way to deantialias a bitmap let me know. I’ve also tried a Sharpen effect but that causes artifacts on edges of controls like TPanel. There are two StackOverflow answers which explain the issue here and here.
I upgraded to Delphi 10 Seattle and FMX.PixelFormats Doesn’t work… Any idea?
procedure TImageCacheLayout.ApplyNoAlphaEdge(ABitmap: TBitmap; OpacityThreshold: integer);
var
bitdata1: TBitmapData;
I: integer;
J: integer;
C: TAlphaColor;
begin
if (ABitmap.Map(TMapAccess.maReadWrite, bitdata1)) then
try
for I := 0 to ABitmap.Width – 1 do
for J := 0 to ABitmap.Height – 1 do
begin
begin
{$IF DEFINED(VER270) OR DEFINED(VER280)}
C := PixelToAlphaColor(@PAlphaColorArray(bitdata1.Data)
[J * (bitdata1.Pitch div PixelFormatBytes[ABitmap.PixelFormat])
+ 1 * I], ABitmap.PixelFormat);
{$ELSE}
C := PixelToAlphaColor(@PAlphaColorArray(bitdata1.Data)
[J * (bitdata1.Pitch div GetPixelFormatBytes(ABitmap.PixelFormat))
+ 1 * I], ABitmap.PixelFormat);
{$ENDIF}
if TAlphaColorRec(C).A