all groups > dotnet drawing api > june 2005 >
You're in the

dotnet drawing api

group:

Drawing of PNGs with transparent pixels


Drawing of PNGs with transparent pixels Alexander Groß
6/27/2005 10:47:52 AM
dotnet drawing api: Hi everyone,

I have a problem I'm currently stuck with. To enable icons in menus, I've
written my own drawing routine for MenuItems (OwnerDraw=true). The icons to
be displayed are PNGs with tranparency and are an embedded resource. On
startup I load the images into an ImageList as described in [1].

So far everything works fine. If I assign one of my icons to a TabPage it is
displayed correctly including transparent regions without artifacts on
edges. The same is true for ToolBarButtons with an appropriate ImageIndex
set.

For MenuItems I use the method Graphics.DrawImage() to draw the icon. But
here, the disturbing artifacts appear again! The same happens if I assign an
image to a PictureBox control.

What seems unlogical to me is that other controls like ToolBarButton draw
the icon correctly. I've set
Graphics.CompositingMode=CompositingMode.SourceOver to ensure that
half-transparent pixels are merged with the background color, but to no
avail.

Does anybody know a way how to get around that?

Thank you very much, best regards,

Alex

[1] http://www.codeproject.com/cs/miscctrl/AlphaImageImagelist.asp
--
_______________________________________

Alexander Groß
Dipl.-Ing. (BA) für Informationstechnik
PLEASEAlexanderGrossREMOVETHIS@gmx.de
http://www.it99.org/axl
ICQ# 36765668
_______________________________________

Re: Drawing of PNGs with transparent pixels Mick Doherty
6/27/2005 9:18:20 PM
If the image is always going to come from an Imagelist, then use
ImageList.Draw() to draw the image instead of Graphics.DrawImage().

Hopefully, that'll solve your problem.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html


[quoted text, click to view]

Re: Drawing of PNGs with transparent pixels Alexander Groß
6/27/2005 11:18:51 PM
Hi Mick,

[quoted text, click to view]
| If the image is always going to come from an Imagelist, then use
| ImageList.Draw() to draw the image instead of Graphics.DrawImage().
|
| Hopefully, that'll solve your problem.

That did the trick! Thank you very much!

Unfortunately one problem persists: I use ControlPaint.DrawImageDisabled()
to paint disabled images (if MenuItem.Enabled==false). Any idea how to get
around that?

Again, thanks. I really was thinking this is a no-go in .NET.

Best regards,

Alex

--
_______________________________________

Alexander Groß
Dipl.-Ing. (BA) für Informationstechnik
PLEASEAlexanderGrossREMOVETHIS@gmx.de
http://www.it99.org/axl
ICQ# 36765668
_______________________________________

Re: Drawing of PNGs with transparent pixels Mick Doherty
6/28/2005 12:00:00 AM
[quoted text, click to view]

The Alpha Channel is a problem in this case.

The imagelist is not very good with Alpha Channels. Could you not bypass it
and use images directly from resource instead.
There has been some work done on the ImageList for VS2005, and although much
better, it's still not perfect in Beta2.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html


Re: Drawing of PNGs with transparent pixels Mick Doherty
6/29/2005 12:00:00 AM
I discovered an API message today which helps to sort this problem out. We
need to extract an Icon from the imagelist and pass this to the method on my
site which returns a 32bit bitmap. We then use a ColorMatrix to paint a
grayscale image if it's disabled.

I was hoping that DrawThemeImage() would do the job, but it doesn't draw a
disabled Image despite the fact that it takes a State argument.

Since no language was specified I'll give the solution in VB, although the
main part of the solution is from my site and is available in both VB and
C#. I'll create a couple of methods, or maybe even a class and upload them
to the site shortly, but in the meantime this is how I tested the code by
painting on a Label.

Note that pngs draw Alpha with a bluish tint (when not disabled) but Icons
don't so if possible use Icons instead of pngs.

\\\
<DllImport("comctl32.dll")> _
Private Shared Function ImageList_GetIcon(ByVal himl As IntPtr, _
ByVal i As Int32, ByVal diFlags As Int32) As IntPtr
End Function

<DllImport("user32.dll")> _
Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As Boolean
End Function

Private Sub Label1_Paint(ByVal sender As Object, _
ByVal e As PaintEventArgs) Handles Label1.Paint

If Label1.ImageIndex = -1 Then Return

Dim hIco As IntPtr = ImageList_GetIcon(ImageList1.Handle, 0, 0)
Dim ico As Icon = Icon.FromHandle(hIco)
Dim bmp As Bitmap = IconToAlphaBitmap(ico)
DestroyIcon(hIco)
ico.Dispose()

Dim cm As New ColorMatrix(New Single()() { _
New Single() {0.3, 0.3, 0.3, 0, 0}, _
New Single() {0.59, 0.59, 0.59, 0, 0}, _
New Single() {0.11, 0.11, 0.11, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})

Dim ia As New ImageAttributes

If Label1.Enabled = False Then
ia.SetColorMatrix(cm)
End If

e.Graphics.DrawImage(bmp, New Rectangle(0, 0, 32, 32), _
0, 0, 32, 32, GraphicsUnit.Pixel, ia)
bmp.Dispose()
ia.Dispose()

End Sub
///

The IconToAlphaBitmap method can be found on my site:
http://dotnetrix.co.uk/misc.html --> Get Alpha Bitmap from 32 bit Icon

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html

Re: Drawing of PNGs with transparent pixels Alexander Groß
7/4/2005 7:12:11 PM
Hi Mick,

| I discovered an API message today which helps to sort this problem
| out. We need to extract an Icon from the imagelist and pass this to
| ...

sorry for my later answer and thanks for the code. My hard drive just blew
up this weekend and I'll hav to reinstall my system before I can test the
code.

I'll post here if I experience any further problems.

Thanks again & best regards,

Alex

--
_______________________________________

Alexander Groß
Dipl.-Ing. (BA) für Informationstechnik
PLEASEAlexanderGrossREMOVETHIS@gmx.de
http://www.it99.org/axl
ICQ# 36765668
_______________________________________

Re: Drawing of PNGs with transparent pixels Mick Doherty
7/4/2005 7:24:18 PM
I posted the code to my site in VB and C# with a slight modification. I
actually use ControlPaint.DrawImageDisabled() now instead of a ColorMatrix,
but the result is the same. I also updated my TabControlEX to draw it's
images using the same method, so I've made use of this solution myself.

http://dotnetrix.co.uk/misc.html --> Draw 32 bit images from an Imagelist.

As an added bonus, 32 bit images are drawn correctly even without Visual
Styles being enabled.


I hope you don't have too much trouble restoring your system. I know in the
past this has happened to me and the first time it happened I didn't have
any backups. I also made the unfortunate error of relying on a RAID mirror
only to have a Windows update destroy the raid drivers. When I finally
traced the problem, my drives were out of sync and chkdsk attempted to fix
some problems resulting in both drives becoming unbootable. I now regularly
back up stuff I want to keep to DVD-RW, so I suppose I learned a lesson
there.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html

OT: Drawing of PNGs with transparent pixels Mick Doherty
7/4/2005 9:03:12 PM
[quoted text, click to view]


It didn't actually change any Raid Drivers, one of the updates
(Hotfix:KB885835) changed Kernel32.dll so that the Raid drivers would not
detect the second drive. It made no difference which was the first drive,
either one would boot independantly, but Raid would fail when both were
connected. I've never actually got around to reinstalling the Raid after
getting updated MainBoard drivers (RAID is a feature of my MainBoard), so it
may be OK now, but this was most annoying when it happened. I'll have to get
round to reinstalling it soon.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html


Re: Drawing of PNGs with transparent pixels Alexander Groß
7/4/2005 9:36:14 PM
Hi Mick,

Mick Doherty
[quoted text, click to view]
| As an added bonus, 32 bit images are drawn correctly even without
| Visual Styles being enabled.

I think I'll also give this piece of code a try :-)

| I hope you don't have too much trouble restoring your system.

Luckily I've got a set of backups on my network server. Nevertheless it's
always annoying to set up the whole system including preferences (especially
those stored to the registry) and to deal with non-LUA-compatible software.
But the new version of the Application Compatibilty Toolkit seems a good
choice for this issue.

| I also made the unfortunate error of relying
| on a RAID mirror only to have a Windows update destroy the raid
| drivers.

This an additional step towards data protection I will take myself when the
repaired drive comes back from Seagate. I'm not quite sure what you mean by
"WU destroyed the RAID drivers". Did WU install drivers that where not
compatible or is this a major issue with RAID on Windows? Getting slightly
off-topic...

Alex

--
_______________________________________

Alexander Groß
Dipl.-Ing. (BA) für Informationstechnik
PLEASEAlexanderGrossREMOVETHIS@gmx.de
http://www.it99.org/axl
ICQ# 36765668
_______________________________________

AddThis Social Bookmark Button