Reputation: 21
I am using this function to draw a png over a TImage on a specific location:
procedure TForm1.PlacePNG(nam: string; px, py: Integer);
var
vPic: TPicture;
vSrc: TGraphic;
begin
vPic := TPicture.Create;
try
vPic.LoadFromFile(Nam);
vSrc := vPic.Graphic;
Image1.Canvas.Draw(px, py, vSrc);
finally
vPic.Free;
end;
end;
My question: what is the best way to do this with part of the png file, without losing its transparency?
Upvotes: 2
Views: 622
Reputation: 109158
This is an interesting question!
Of course, drawing the entire PNG is trivial:
procedure TForm1.FormCreate(Sender: TObject);
var
bg, fg: TPngImage;
begin
bg := TPngImage.Create;
try
bg.LoadFromFile('K:\bg.png');
fg := TPngImage.Create;
try
fg.LoadFromFile('K:\fg.png');
Image1.Picture.Graphic := bg;
Image2.Picture.Graphic := fg;
fg.Draw(bg.Canvas, Rect(0, 0, fg.Width, fg.Height));
Image3.Picture.Graphic := bg;
finally
fg.Free;
end;
finally
bg.Free;
end;
end;
To draw only a part, one possible solution is to obtain the images as 32-bpp RGBA bitmaps and then use the Windows API, specifically, the AlphaBlend
function:
procedure TForm1.FormCreate(Sender: TObject);
var
bg, fg: TPngImage;
bgbm, fgbm: TBitmap;
BlendFunction: TBlendFunction;
begin
// Load background PNG
bg := TPngImage.Create;
try
bg.LoadFromFile('K:\bg.png');
// Load foreground PNG
fg := TPngImage.Create;
try
fg.LoadFromFile('K:\fg.png');
// Preview background and foreground
Image1.Picture.Graphic := bg;
Image2.Picture.Graphic := fg;
// Create background BMP
bgbm := TBitmap.Create;
try
bgbm.Assign(bg);
// Create foreground BMP
fgbm := TBitmap.Create;
try
fgbm.Assign(fg);
// Blend PART OF foreground BMP onto background BMP
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.SourceConstantAlpha := 255;
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
if not Winapi.Windows.AlphaBlend(
bgbm.Canvas.Handle,
100,
100,
200,
200,
fgbm.Canvas.Handle,
200,
200,
200,
200,
BlendFunction
) then
RaiseLastOSError;
// Preview result
Image3.Picture.Graphic := bgbm;
finally
fgbm.Free;
end;
finally
bgbm.Free;
end;
finally
fg.Free;
end;
finally
bg.Free;
end;
end;
Upvotes: 5