I want to add transparent and partly transparent regions on a Image.Bitmap. I found out, that the transparency regions does not affect as expected: The RGB parts of the TAlphaColor value does affect more than they should - so it is e.g. not possible to build a clean transparency gradient.
To show this I buildt this small example: If I set the alpha value of a TAlphaColor value to "0", the pixel should be fully transparent - independend of the other RGB values of the value.
Delphi does not behave as expected: Even if set the Alpha Value to "0", the foreground bitmap is not fully transparent. (If I set the whole TAlphaColor to $00000000 it is fully transparent - but this is not what I want)
Full Source Code:
Form, pas code:
unit Main;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, FMX.Objects;
type
TfmMain = class(TForm)
imgBack: TImage;
imgFront: TImage;
procedure FormCreate(Sender: TObject);
private
public
end;
var
fmMain: TfmMain;
implementation
{$R *.fmx}
procedure ImgInitP(xImg:TImage; xCl:TAlphaColor);
var
xCorners: TCorners;
begin
xImg.Bitmap := TBitmap.Create;
xImg.Bitmap.SetSize(Round(xImg.Width), Round(xImg.Height));
xImg.Bitmap.Canvas.Fill.Color := xCl;
xImg.Bitmap.Canvas.BeginScene;
try
xImg.Bitmap.Canvas.FillRect(TRectF.Create(xImg.ClipRect),0,0,xCorners,1);
finally
xImg.Bitmap.Canvas.EndScene;
end;
end;
procedure TfmMain.FormCreate(Sender: TObject);
var
iX: Integer;
iY: Integer;
xBitmapData: TBitmapData;
xCl: TAlphaColor;
begin
// init 2 images
ImgInitP(imgBack,$ffbb2211);
ImgInitP(imgFront,$ff2233dd);
// set some pixels transparent in foreground picture
if imgFront.Bitmap.Map(TMapAccess.ReadWrite,xBitmapData) then begin
try
for iX := 10 to 30 do begin
for iY := 10 to 20 do begin
// set alpha channel of this pixels to zero
xCl := xBitmapData.GetPixel(iX,iY);
TAlphaColorRec(xCl).A := 0;
xBitmapData.SetPixel(iX,iY,xCl);
end;
end;
finally
imgFront.Bitmap.Unmap(xBitmapData);
end;
end;
end;
end.
Form, fmx code:
object fmMain: TfmMain
Left = 0
Top = 0
Caption = 'Main'
ClientHeight = 116
ClientWidth = 248
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop, iPhone, iPad]
OnCreate = FormCreate
DesignerMobile = False
DesignerWidth = 0
DesignerHeight = 0
DesignerDeviceName = ''
DesignerOrientation = 0
DesignerOSVersion = ''
object imgBack: TImage
MultiResBitmap = <
item
end>
Height = 73.000000000000000000
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
Width = 89.000000000000000000
end
object imgFront: TImage
MultiResBitmap = <
item
end>
Height = 73.000000000000000000
Position.X = 24.000000000000000000
Position.Y = 24.000000000000000000
Width = 89.000000000000000000
end
end
Project code, dpr:
program TestAlpha;
uses
FMX.Forms,
Main in 'Main.pas' {fmMain};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TfmMain, fmMain);
Application.Run;
end.
Screenshot of the running programm: The pink rectangle has alpha value of "0" - but still is not fully transparent.
Working on Delphi XE6, FMX, Win32.
xCl := xBitmapData.GetPixel(iX,iY); xCl := UnpremultiplyAlpha(xCl); TAlphaColorRec(xCl).A := 0; xCl := PremultiplyAlpha(xCl); xBitmapData.SetPixel(iX,iY,xCl);
will solve the problem in this example - but not the problem in general: When changing the transparency of a pixel, the color information is lost. – BitBumper