我想在Image.Bitmap上添加透明和部分透明的区域。 我发现,透明度区域不会像预期的那样影响: TAlphaColor值的RGB部分确实影响得比它们应该的多 - 所以它是例如它不可能建立一个 清洁透明度渐变。
为了表明这一点,我构建了这个小例子: 如果我将TAlphaColor值的alpha值设置为“0”,则像素应该是完全透明的 - 独立于该值的其他RGB值。
Delphi的行为不符合预期: 即使将Alpha值设置为“0”,前景位图也不是完全透明的。 (如果我将整个TAlphaColor设置为$ 00000000它是完全透明的 - 但这不是我想要的)
完整源代码:
表格,密码:
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.
表单,fmx代码:
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
项目代码,dpr:
program TestAlpha;
uses
FMX.Forms,
Main in 'Main.pas' {fmMain};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TfmMain, fmMain);
Application.Run;
end.
正在运行的程序的屏幕截图: 粉红色矩形的alpha值为“0” - 但仍然不完全透明。
使用Delphi XE6,FMX,Win32。
答案 0 :(得分:0)
正如我上面的评论:问题与Delphi中的预乘alpha模式有关。
如果您需要记住有关透明区域的颜色信息,则必须使用位图副本才能访问原始颜色信息。
如果应该连接一些透明区域,透明度最低可以解决问题:
var
bNewAlpha: byte;
bOldAlpha: byte;
begin
// input parameter of new alpha
bNewAlpha := 123;
//
xCl := xBitmapData.GetPixel(iX,iY);
xCl := UnpremultiplyAlpha(xCl);
bOldAlpha := TAlphaColorRec(xCl).A;
bNewAlpha := Min(bNewAlpha,bOldAlpha);
TAlphaColorRec(xCl).A := bNewAlpha;
xCl := PremultiplyAlpha(xCl);
xBitmapData.SetPixel(iX,iY,xCl);
答案 1 :(得分:0)
xImg.Bitmap.Canvas.FillRect(TRectF.Create(xImg.ClipRect),0,0,xCorners,<强> 1 强>);
通过将最后一个参数(AOpacity)设置为介于0和1之间的值来获得中间不透明度。尝试...
xImg.Bitmap.Canvas.FillRect(TRectF.Create(xImg.ClipRect),0,0,xCorners,0.5);