Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-06

Converting Icon from Windows handle to TBitmap with transparency

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

cobines

Hello everyone.

I want to convert an icon retrieved by Windows API to a TBitmap saving transparency. As I understand transparency can be achieved by:
- using an additional Mask bitmap
- using 32bpp TBitmap with alpha channel

Having the handle to an icon from WINAPI, I convert it to TBitmap the following way:

function IconToBitmap(h: HICON): TBitmap;
var
  icon: TIcon;
begin
  icon := TIcon.Create;
  icon.Handle := h;
  Result := TBitmap.Create;
  Result.Assign(icon);
  icon.Free;
end;

But this does not preserve transparency. I have to add:

Result.Mask(Result.TransparentColor);

Is this the correct way?

Why Icon does not automatically have a Mask? It does have TransparentMode and TransparentColor correctly assigned. TransparentColor is copied to TBitmap but the Mask is not copied or not automatically created.

cobines

Reply by email

cobines
to cobines

2011/6/8 cobines :

Show quoted text 31 lines
Hello everyone. I want to convert an icon retrieved by Windows API to a TBitmap saving transparency. As I understand transparency can be achieved by: - using an additional Mask bitmap - using 32bpp TBitmap with alpha channel Having the handle to an icon from WINAPI, I convert it to TBitmap the following way: function IconToBitmap(h: HICON): TBitmap; var ?icon: TIcon; begin ?icon := TIcon.Create; ?icon.Handle := h; ?Result := TBitmap.Create; ?Result.Assign(icon); ?icon.Free; end; But this does not preserve transparency. I have to add: Result.Mask(Result.TransparentColor); Is this the correct way? Why Icon does not automatically have a Mask? It does have TransparentMode and TransparentColor correctly assigned. TransparentColor is copied to TBitmap but the Mask is not copied or not automatically created.

I finally had time to do some digging.

Turns out Mask bitmap exists in both TIcon and TBitmap (mask image is copied). Problem is Masked is False in TBitmap. This is because in

procedure TRasterImage.Assign(Source: TPersistent);

there is line

    FMasked := SrcImage.FMasked;

which is wrong. It should be :

    FMasked := SrcImage.Masked;

FMasked is never set to True for TCustomIcon. Instead Masked property is overridden to always return True. Therefore after TBitmap.Assign(TIcon) FMasked is False, while it should be True.

Also a question:
Why TIcon always has Masked=True?

Icons with alpha channel don't work properly with TIcon and they don't use Mask. Is support for alpha channel icons simply not implemented?

cobines

Reply by email

cobines
to cobines

2011/7/15 cobines :

Show quoted text 5 lines
Also a question: Why TIcon always has Masked=True? Icons with alpha channel don't work properly with TIcon and they don't use Mask. Is support for alpha channel icons simply not implemented?

More question related to this.

In

function TWin32WidgetSet.RawImage_FromBitmap(out ARawImage: TRawImage;
ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean;

there is code:

  if ASize < SizeOf(WinDIB) then
    ARawImage.Description.AlphaPrec := 0;

It seems that TIconInfo.HBITMAP handle (which in my case is a default system folder icon) has not been created with CreateDIBSection therefore GetObject returns plain HBITMAP and not DIBSECTION and the code above disables alpha channel.

However, when I remove that code icons with alpha channel are displayed properly. AlphaPrec=8, pixelFormat is pf32bit. Masked=True but that doesn't seem to matter.

The code was added in

http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=13314

and fixed bug

http://bugs.freepascal.org/view.php?id=10299

I don't understand why it says:

"if it is not DIB then alpha in bitmaps is not supported => use 0 alpha prec"

since it seems HICON bitmaps is not DIB but it has alpha channel.

cobines

Reply by email

Maxim Ganetsky
to cobines: 2011/6/8 cobines : I finally had time to do some digging. Turns out Mask bitmap exists in…

15.07.2011 2:10, cobines ?????:

Show quoted text 51 lines
2011/6/8 cobines: > Hello everyone. > > I want to convert an icon retrieved by Windows API to a TBitmap saving > transparency. As I understand transparency can be achieved by: > - using an additional Mask bitmap > - using 32bpp TBitmap with alpha channel > > Having the handle to an icon from WINAPI, I convert it to TBitmap the > following way: > > function IconToBitmap(h: HICON): TBitmap; > var > icon: TIcon; > begin > icon := TIcon.Create; > icon.Handle := h; > Result := TBitmap.Create; > Result.Assign(icon); > icon.Free; > end; > > But this does not preserve transparency. I have to add: > > Result.Mask(Result.TransparentColor); > > Is this the correct way? > > Why Icon does not automatically have a Mask? It does have > TransparentMode and TransparentColor correctly assigned. > TransparentColor is copied to TBitmap but the Mask is not copied or > not automatically created. I finally had time to do some digging. Turns out Mask bitmap exists in both TIcon and TBitmap (mask image is copied). Problem is Masked is False in TBitmap. This is because in procedure TRasterImage.Assign(Source: TPersistent); there is line FMasked := SrcImage.FMasked; which is wrong. It should be : FMasked := SrcImage.Masked; FMasked is never set to True for TCustomIcon. Instead Masked property is overridden to always return True. Therefore after TBitmap.Assign(TIcon) FMasked is False, while it should be True.

Please create a bug report.

Show quoted text 5 lines
Also a question: Why TIcon always has Masked=True? Icons with alpha channel don't work properly with TIcon and they don't use Mask. Is support for alpha channel icons simply not implemented?
Best regards, Maxim Ganetsky mailto:

Reply by email