Reputation: 3033
I can get a 32-bit image to be displayed in TImage with GDIPlus that has partial (masked) transparency but the alpha values are either 0 or 255 with no values in between. I have tried loading PngImage, 32-bit bitmaps and icons all produce the same... masked transparency but not full transparency.
Is there another way to get TImage to display a GDI+ graphic with full transparency as shown in the Desired Result image?
GDI Plus After Open
Desired Result
procedure TFormMain.Open1Click ( Sender: TObject );
// Load a GDIPlus Bitmap into TImage
var
GPBitmap: TGPBitmap;
iHBitmap: HBITMAP;
iStatus: TStatus;
const
TRANS_COLOR = clBlack;
begin
if OpenPictureDialog1.Execute then
begin
FilePath := OpenPictureDialog1.FileName;
begin
GPBitmap := TGpBitmap.Create ( FilePath );
try
iStatus := GPBitmap.GetHBITMAP ( aclBlack, iHBitmap );
// As best as I can determine from the internet, the GetHBitmap which is needed to assign a GPbitmap to TImage
// does not hold an alphachannel, so loaded images alpha are either 0 or 255, but drawing with alphachannel values does work.
if iStatus = Ok then
begin
Image1.Picture.Bitmap.Handle := iHBitmap;
Image1.Picture.Bitmap.TransparentColor := Image1.Picture.Bitmap.Canvas.Pixels [ 0, Image1.Picture.Bitmap.Height - 1 ];
StatusBar1.Panels [ 0 ].Text := FileCtrl.MinimizeName ( ExtractFileDir ( FilePath ), Canvas, 200 ); // Folder
StatusBar1.Panels [ 1 ].Text := FileCtrl.MinimizeName ( ExtractFileName ( FilePath ), Canvas, 75 ); // Filename
StatusBar1.Panels [ 2 ].Text := 'Width: ' + IntegerToString ( Image1.Picture.Bitmap.Width ); // Width
StatusBar1.Panels [ 3 ].Text := 'Height: ' + IntegerToString ( Image1.Picture.Bitmap.Height ); // Height
StatusBar1.Panels [ 4 ].Text := BitDepthToColorString ( GetPixelFormatSize ( GPBitmap.GetPixelFormat ) ); // Bitdepth
Image1.Refresh;
end;
finally
GPBitmap.Free;
end;
end;
end;
end;
Upvotes: 3
Views: 2389
Reputation: 54772
What you need to do is to choose a background color that will blend with the surface that the image is drawn on when it is transferred. I.e. instead of
iStatus := GPBitmap.GetHBITMAP ( aclBlack, iHBitmap );
use
iStatus := GPBitmap.GetHBITMAP(ColorRefToARGB(ColorToRGB(clBtnFace)), iHBitmap);
if the image is on a default colored form for instance.
At this point you already know that the image has no alpha channel, but it has been flattened using a suitable color. The Transparent..
properties of 'TBitmap' will not help with partial transparency. If you set the Transparent
property of the TBitmap
, it will still be like the first image of your question when you put it on a different colored background, probably with a nicer edge color. In any case, if you use it, do not forget to set the 'TransparentColor' to 'clBtnFace' instead of 'clBlack'.
Upvotes: 2