我很难在TBitmap
上透明地TDirect2DCanvas
绘制TBitmap
而不会失去透明度。
创建一个bmp := TBitmap.Create;
bmp.Canvas.Brush.Handle := 0;
bmp.SetSize(100, 100);
bmp.Canvas.Brush.Color := clRed;
bmp.Transparent := true;
bmp.TransparentColor := clRed;
bmp.Canvas.Rectangle(bmp.Canvas.ClipRect);
bmp.Canvas.Pen.Color := clGreen;
bmp.Canvas.Ellipse(bmp.Canvas.ClipRect);
作为我的绘图操作的后台缓冲区,如下所示:
TDirect2DCanvas
然后我需要将它绘制到我的TBitmap
上,但是下面绘制了TForm.Canvas
但删除了所有透明度 - 背景颜色绘制为红色,而如果我只是绘制到{{1}然后背景是透明的。
// Drawing onto the TDirect2DCanvas results in a red background
AEventArgs.Canvas.Draw(0, 0, bmp);
// Drawing onto the TForm.Canvas gives the correct result
Self.Canvas.Draw(0, 0, bmp);
我的理解现在引导我进入ID2D1Bitmap
和IWICBitmap
接口,因此,我可以尝试使用以下代码从ID2D1Bitmap
创建TBitmap
(和< em>假设像素格式被复制了一遍):
var
bmp : TBitmap;
temp : ID2D1Bitmap;
begin
// Code to initialize the TBitmap goes here (from above)
// Create an ID2D1Bitmap from a TBitmap
temp := AEventArgs.Canvas.CreateBitmap(bmp);
// Draw the ID2D1Bitmap onto the TDirect2DCanvas
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);
现在我有ID2D1Bitmap
,结果仍然相同 - 红色背景没有透明度。我认为Direct2D方面使用不同的透明方法是完全可行的,但是查看ID2D1Bitmap
的属性并没有提供任何线索。
我的下一个猜测是沿着IWICBitmap
界面。
最终,我的问题是:是否有一个更直接或更明显的事情,我从上面错过了,这将允许透明TBitmap
被绘制到TDirect2DCanvas
表面?或者为了保持透明度,所有这些都是必要的吗?
更新
好的,所以经过多一点挖掘之后,我现在可以将TBitmap
转换为IWICBitmap
然后转换为ID2D1Bitmap
但问题仍然存在 - 透明度存在渲染到TBitmap
时,TDirect2DCanvas
中的// Create the IWICBitmap from the TBitmap
GetWICFactory.CreateBitmapFromHBITMAP(bmp.Handle, bmp.Palette, WICBitmapUsePremultipliedAlpha, wic);
wic.GetPixelFormat(pif);
// The PixelFormat is correct as `GUID_WICPixelFormat32bppPBGRA` which is
// B8G8R8A8_UNORM and PREMULTIPLIED
// Create the IWICFormatConverter
GetWICFactory.CreateFormatConverter(fc);
fc.Initialize(wic, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0.0, WICBitmapPaletteTypeCustom);
// Now, create the ID2D1Bitmap
AEventArgs.Canvas.RenderTarget.CreateBitmapFromWicBitmap(fc, nil, temp);
temp.GetPixelFormat(fmt);
// Here, PixelFormat is correct matching the PixelFormat from the IWICBitmap
// Draw the bitmap to the Canvas
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);
不会被复制。
// Create the canvas
fCanvas := TDirect2DCanvas.Create(Self.Handle);
fCanvas.RenderTarget.GetPixelFormat(pf);
// This gives me a PixelFormat of
// B8G8R8A8_UNORM but D2D1_ALPHA_MODE_IGNORE
结果仍然是一个不透明的位图。
所以我最后要研究的是ID2D1RenderTarget的PixelFormat,它是TDirect2DCanvas的底层渲染目标。
ID2D1RenderTarget
因此,我猜测真正的问题与 create table ma_user.test_mview
(
col1 int,
col2 int,
date_col timestamp
)
insert all
into ma_user.test_mview values (1,1,SYSDATE)
into ma_user.test_mview values (1,2,SYSDATE + 10/1440)
into ma_user.test_mview values (1,2,SYSDATE + 30/86400)
into ma_user.test_mview values (2,1,SYSDATE + 1/48)
into ma_user.test_mview values (2,2,SYSDATE + 1/24)
into ma_user.test_mview values (2,2,SYSDATE + 1/72)
into ma_user.test_mview values (2,3,SYSDATE + 1/96)
SELECT * FROM dual;
CREATE MATERIALIZED VIEW ma_user.test_mat_view1
BUILD IMMEDIATE
REFRESH
complete
ON COMMIT
as
select col1,col2 from ma_user.test_mview
where current_date > date_col;
PixelFormat忽略alpha这一事实有关。
答案 0 :(得分:2)
真正的问题不在于您调用的方法,而是在VCL应用程序中默认情况下TBitmap使用24位RGB像素格式的剪切事实,该格式没有Alpha透明度所需的Alpha通道。
如果您想对TBitmap使用Alpha透明度,首先需要将其像素格式设置为2016-07-19 17:48:36,650 DEBUG: security.web.FilterChainProxy - / at position 1 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-07-19 17:48:36,650 DEBUG: web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-07-19 17:48:36,650 DEBUG: web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@53b1e801. A new one will be created.
。
https://stackoverflow.com/a/4680460/3636228
另外,不要忘记为希望它透明的每个像素将Alpha通道设置为0。
您看到Direct2D不支持与VCL中使用的相同的透明度,您可以在其中简单地设置透明色,并忽略该特定颜色的每个像素。
答案 1 :(得分:1)
如果您查看 TDirect2DCanvas.CreateBitmap 的源代码,您会看到:
...
if (Bitmap.PixelFormat <> pf32bit) or (Bitmap.AlphaFormat = afIgnored) then
BitmapProperties.pixelFormat.alphaMode := D2D1_ALPHA_MODE_IGNORE
else
BitmapProperties.pixelFormat.alphaMode := D2D1_ALPHA_MODE_PREMULTIPLIED;
所以要让它工作,你必须符合条件:
bmp.PixelFormat := pf32bit;
bmp.AlphaFormat := TAlphaFormat.afPremultiplied;
然后你必须准备每个像素的 alpha 通道。在您的情况下,红色是透明的,因此您应该执行以下操作:
for y := 0 to bmp.Height - 1 do begin
Line := bmp.Scanline[y];
for x := 0 to bmp.Width - 1 do begin
if (line[x].r =255) and (line[x].g = 0) and (line[x].b = 0) then
Line[x].A := 0
else
Line[x].A := 255;
end;
然后它来了:
temp := AEventArgs.Canvas.CreateBitmap(BMP);
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);
我花了整个周末才自己弄明白,希望对你或其他人有帮助。