[英]Transparent PNG image loaded from resource file, resized with Grapics32 and drawn on the Canvas
我需要一點幫助...
我的應用程序資源中有一個透明的 PNG 圖像。 到目前為止,我將它加載到TPngImage
並使用Canvas.Draw(X, Y, PngImage);
在屏幕上繪制它Canvas.Draw(X, Y, PngImage);
. 而且是透明繪制的。 現在我將我的應用程序更新為 DpiAware,我需要縮放所有圖像。 我需要一個高質量的重采樣器,我選擇使用 Graphics32。 我設法進行了重新采樣,但我不知道如何保持透明度......我嘗試了所有我能想到的......以下代碼的結果是在透明區域用黑色繪制的圖像...... .
Foto32, Buff: TBitmap32;
FotoPng: TPngImage;
constructor TForm.Create(AOwner: TComponent);
const BkgHeight = 380;
var Res: TKernelResampler;
SRect, DRect: TRect;
ImgWidth: Integer;
begin
inherited;
Buff:= TBitmap32.Create;
Res:= TKernelResampler.Create;
Res.Kernel:= TLanczosKernel.Create;
FotoPng:= TPngImage.Create;
FotoPng.Transparent:= True;
FotoPng.TransparentColor:= clBlack;
FotoPng.LoadFromResourceName(HInstance, 'BKG_FOTO');
Foto32:= TBitmap32.Create;
Foto32.DrawMode:= dmBlend;
Foto32.CombineMode:= cmMerge;
Foto32.OuterColor:= clBlack;
Foto32.Canvas.Brush.Style:= bsClear;
Foto32.SetSize(FotoPng.Width, FotoPng.Height);
FotoPng.Draw(Foto32.Canvas, Rect(0, 0, FotoPng.Width, FotoPng.Height));
ImgWidth:= Round(Real(Foto32.Width / Foto32.Height) * BkgHeight);
SRect:= Rect(0, 0, Foto32.Width, Foto32.Height);
Buff.DrawMode:= dmBlend;
Buff.CombineMode:= cmMerge;
Buff.OuterColor:= clBlack;
Buff.Canvas.Brush.Style:= bsClear;
Buff.SetSize(Scale(ImgWidth), Scale(BkgHeight));
DRect:= Rect(0, 0, Buff.Width, Buff.Height);
Res.Resample(Buff, DRect, DRect, Foto32, SRect, dmTransparent {dmBlend}, nil);
end;
procedure TForm.Paint;
begin
// ....
Buff.DrawTo(Canvas.Handle, X, Y);
end;
這是我編譯成資源的透明PNG圖片: https : //postimg.cc/3yy3wrJB
我在這里發現了一個類似的問題,但我沒有將圖像與TImage
一起使用,而是直接在畫布上繪制它。 在唯一的答案中,大衛說:
無論如何,如果是這樣,我會將 TImage 的透明度支持與 TBitmap32 的重采樣能力結合起來,以這種方式構建解決方案。 將原始圖像保存在 TBitmap32 實例中。 每當您需要將其加載到 TImage 組件中時,例如重新調整大小時,請使用 TBitmap32 執行內存中調整大小並加載重新調整大小的圖像。
這正是我想要做的,但我不知道為什么透明度不起作用。 有任何想法嗎 ?
您的問題似乎是將緩沖區繪制到屏幕上的問題。 Bitmap32 使用StretchDIBits
進行繪畫,它忽略了 alpha 通道。
您可以使用AlphaBlend
函數來繪制圖像:
procedure TForm1.FormPaint(Sender: TObject);
var
BF: TBlendFunction;
begin
BF.BlendOp := AC_SRC_OVER;
BF.BlendFlags := 0;
BF.SourceConstantAlpha := 255;
BF.AlphaFormat := AC_SRC_ALPHA;
Winapi.Windows.AlphaBlend(Canvas.Handle, 0, 0, Buff.Width, Buff.Height,
Buff.Canvas.Handle, 0, 0, Buff.Width, Buff.Height, BF);
end;
或者將您的 TBitmap32 轉換為 Delphi TBitmap 並使用 VCL 繪制它:
procedure TForm1.FormPaint(Sender: TObject);
var
Bmp: TBitmap;
I: Integer;
begin
Bmp := TBitmap.Create;
try
Bmp.PixelFormat := pf32bit;
Bmp.AlphaFormat := afDefined;
Bmp.SetSize(Buff.Width, Buff.Height);
for I := 0 to Buff.Height - 1 do
Move(Buff.ScanLine[I]^, Bmp.ScanLine[I]^, Buff.Width * 4);
Canvas.Draw(0, 0, Bmp);
finally
Bmp.Free;
end;
end;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.