在delphi(Firmonkey)下,在android下如果重要,我需要使位图的特定部分透明,即位图的圆角,如下图所示:
位图是通过Control.MakeScreenShot
生成的。
我尝试用透明像素替换所有左上角的红色像素,如下所示:
if fScreenShot.Map(TMapAccess.ReadWrite, M) then
try
//make the top left corner transparent
for x := 0 to fScreenShot.Width - 1 do begin
aContinue := False;
for y := 0 to fScreenShot.Height - 1 do begin
if M.GetPixel(X,Y) = _FrameBGColor then begin
aContinue := True;
M.SetPixel(X,Y,TalphaColorRec.Null);
end
else break;
end;
if not aContinue then break;
end;
finally
fScreenShot.Unmap(M);
end;
但指令fScreenShot.Map(TMapAccess.ReadWrite,M)非常慢(大约200毫秒)所以我不能这样做:(有没有其他方法我可以用透明替换这个红色颜色?
注意:现在(我只关注android / ios,所以在 OpenGL )我发现在画布中清除某个区域的唯一方法就是< / p>
Canvas.SaveState;
Canvas.IntersectClipRect(TRectF.create());
Canvas.Clear(TalphaColorRec.Null);
canvas.RestoreState
然而,这只适用于矩形区域,不能应用于我的问题:(
注意2 我即将使用blending := False
找到可行的解决方案:
Canvas.blending := False;
Canvas.Fill.Color := $00000000;
Canvas.Fill.Kind := TbrushKind.Solid;
canvas.FillRect(TRectF.create(100,100,200,200), //const ARect: TRectF;
0, 0, //const XRadius, YRadius: Single;
[], //const ACorners: TCorners;
1, // const AOpacity: Single;
TCornerType.round);
Canvas.blending := true;
此代码实际上清除了矩形。看起来不错,这就是我想要的角落。所以我尝试将FillRect
替换为fillpath
,我很不走运,这与fillpath
无关:(任何想法?它适用于fillEllipse
,FillRect
等等,但只是fillpath
它不起作用:(
答案 0 :(得分:1)
如果有人发现这个并且也想要解决方案,这就是我最终做到的。最后,我可以说,做这样一个琐碎的想法,它的缝很复杂:(
{************************************}
{$IF defined(IOS) or defined(android)}
type
_TcustomCanvasGPUProtectedAccess = class(TcustomCanvasGPU);
{$ENDIF}
{************************************}
{$IF defined(IOS) or defined(android)}
procedure ClearRoundCorner(const aCanvas: Tcanvas; const ARect: TRectF; const ACorner: TCorner);
const
MinFlatDistance = 4;
var
Vertices: TCanvasHelper.TVertexArray;
Colors: TCanvasHelper.TAlphaColorArray;
Indices: TCanvasHelper.TIndexArray;
Index, SubdivCount, VertexCount: Integer;
Offset: integer;
Angle: Single;
Radius: TPointF;
Center, CurPt, OriPt: TPointF;
begin
Radius.X := ARect.Width;
Radius.Y := ARect.Height;
SubdivCount := (Max(Ceil(2 * Pi * Max(Radius.X, Radius.Y) / MinFlatDistance), 40) div 4) * 4; // https://quality.embarcadero.com/browse/RSP-15206
VertexCount := (SubdivCount div 4) + 1;
case ACorner of
TCorner.BottomRight: begin
Offset := 0;
Center.X := ARect.left;
Center.Y := ARect.top;
OriPt.X := ARect.left + aRect.width;
OriPt.Y := ARect.bottom + aRect.height;
end;
TCorner.BottomLeft: begin
Offset := (SubdivCount div 4);
Center.X := ARect.Right;
Center.Y := ARect.top;
OriPt.X := ARect.left - aRect.width;
OriPt.Y := ARect.bottom + aRect.height;
end;
TCorner.TopLeft: begin
Offset := (SubdivCount div 4) * 2;
Center.X := ARect.right;
Center.Y := ARect.bottom;
OriPt.X := ARect.left - ARect.width;
OriPt.Y := ARect.top - aRect.height;
end;
TCorner.TopRight: begin
Offset := (SubdivCount div 4) * 3;
Center.X := ARect.left;
Center.Y := ARect.Bottom;
OriPt.X := ARect.right + aRect.width;
OriPt.Y := ARect.top - aRect.height;
end;
end;
SetLength(Vertices, 1 + VertexCount);
SetLength(Colors, 1 + VertexCount);
SetLength(Indices, VertexCount * 3);
CurPt := OriPt;
//if Assigned(TransformCallback) then
// TransformCallback(CurPt);
CurPt := _TcustomCanvasGPUProtectedAccess(aCanvas).TransformPoint(CurPt);
//if FAlignToPixels then
// AlignToPixel(Result);
Vertices[0] := CurPt;
Colors[0] := TalphaColorRec.null;
for Index := 0 to VertexCount - 1 do
begin
if index = VertexCount - 1 then CurPt := OriPt
else begin
Angle := (Offset + Index) * 2 * Pi / SubdivCount;
CurPt.X := Cos(Angle) * Radius.X;
CurPt.Y := Sin(Angle) * Radius.Y;
CurPt.Offset(Center);
end;
//if Assigned(TransformCallback) then
// TransformCallback(CurPt);
CurPt := _TcustomCanvasGPUProtectedAccess(aCanvas).TransformPoint(CurPt);
//if FAlignToPixels then
// AlignToPixel(Result);
Vertices[1 + Index] := CurPt;
Colors[1 + Index] := TalphaColorRec.null;
Indices[(Index * 3) + 0] := 0;
Indices[(Index * 3) + 1] := 1 + Index;
Indices[(Index * 3) + 2] := 1 + ((1 + Index) mod VertexCount);
end;
CanvasHelper.FillTriangles(Vertices, Colors, Indices, Length(Vertices), VertexCount);
end;
{$ENDIF}