如何从32 bpp w / o的TBitmap实例创建一个临时DIB部分的alpha混合图标/游标(间接)? [英] How can I create alpha blended icon/cursor (indirect) from the TBitmap instance of 32 bpp w/o making an temporary DIB section?
问题描述
根据 MS KB条目,在 CreateIconIndirect中有一个怪癖使用
BITMAPV5HEADER
创建可识别
HBITMAP
传递到 CreateDIBSection
(和BGRA频道布局)。
According to MS KB entry, there is a quirk in CreateIconIndirect
which recognizes HBITMAP
s been created with BITMAPV5HEADER
passed to CreateDIBSection
(and BGRA channel layout).
但是, TBitmap
具有(PixelFormat = pf32bit)和(AlphaFormat = afDefined)
(由于其他目的而表现为alpha混合)当它的句柄
被引用时不被识别为用于创建图标的有效Alpha混合位图光标。
However, TBitmap
instances with (PixelFormat = pf32bit) and (AlphaFormat = afDefined)
(behaving as alpha blended for the other purposes) when referred by its Handle
s are not being recognized as valid alpha blended bitmaps for creation of icons or cursors.
目前,我必须使用描述的API调用创建一个完整的TBitmap副本(见)使 CreateIconIndirect
接受一个位图句柄为alpha混合。如何克服这种笨拙?
Currently, I have to create a full copy of TBitmap using described API calls (see) to make CreateIconIndirect
accept a bitmap handle as alpha blended. How do I overcome this clumsiness?
推荐答案
这里有一个例子:
procedure TForm1.Button1Click(Sender: TObject);
const
crAlpha = TCursor(-25);
var
Bmp: TBitmap;
Px: PRGBQuad;
X, Y: Integer;
BmpMask: TBitmap;
II: TIconInfo;
AlphaCursor: HCURSOR;
begin
Bmp := TBitmap.Create;
Bmp.PixelFormat := pf32bit;
Bmp.Canvas.Brush.Color := clWhite;
Bmp.SetSize(32, 32);
Bmp.Canvas.Font.Style := [fsBold];
Bmp.Canvas.Font.Color := clRed;
Bmp.Canvas.TextOut(1, 10, 'alpha');
for Y := 0 to (Bmp.Height - 1) do
begin
Px := Bmp.ScanLine[Y];
for X := 0 to (Bmp.Width - 1) do begin
if DWORD(Px^) = DWORD(clWhite) then
Px.rgbReserved := $00
else
Px.rgbReserved := $FF;
Inc(Px);
end;
end;
BmpMask := TBitmap.Create;
BmpMask.SetSize(Bmp.Width, Bmp.Height);
II.fIcon := False;
II.xHotspot := 32;
II.yHotspot := 32;
II.hbmMask := BmpMask.Handle;
II.hbmColor := Bmp.Handle;
AlphaCursor := CreateIconIndirect(II);
Win32Check(AlphaCursor <> 0);
BmpMask.Free;
Bmp.AlphaFormat := afDefined; // AlphaBlend below, premultiply channels
Canvas.Draw(0, 0, Bmp); // test draw
Bmp.Free;
Screen.Cursors[crAlpha] := AlphaCursor;
Cursor := crAlpha;
end;
(顶部的alpha是测试绘制,另一个是光标)
(Top 'alpha' is test draw, the other is a cursor)
这篇关于如何从32 bpp w / o的TBitmap实例创建一个临时DIB部分的alpha混合图标/游标(间接)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!