This message was discovered on microsoft.public.dotnet.framework.windowsforms.
| Yuval Naveh |
Hello, I have encountered a problem while trying to display images in the ListView control. I am using Visual Studio 2003/C# on windows 2000 professional SP4. My images are 32 bit PNG with alpha channel that has 256 levels. After adding them to an ImageList component, and attaching the image list to a list view, the images show thier alpha channel pixels as opaque pixels. The problem seems to be with ImageList. This subject has come up already in this newsgroup, and I saw no solution for the problem.
Someone posted an untested code that is supposed to fix the problem, it compiles and runs but does not work.
Can anyone suggest a solution (a working and tested code)?
Thanks Yuval Naveh Actimize Israel
The code that was supposed to fix the problem:
[DllImport("comctl32.dll")] static extern bool ImageList_Add( IntPtr hImageList, IntPtr hBitmap, IntPtr hMask ); [DllImport("kernel32.dll")] static extern bool RtlMoveMemory( IntPtr dest, IntPtr source, int dwcount); [DllImport("gdi32.dll")] static extern IntPtr CreateDIBSection(IntPtr hdc, [In, MarshalAs(UnmanagedType.LPStruct)] BITMAPINFO pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
[StructLayout(LayoutKind.Explicit)] public class BITMAPINFO { [FieldOffset(0)] public Int32 biSize; [FieldOffset(4)] public Int32 biWidth; [FieldOffset(8)] public Int32 biHeight; [FieldOffset(12)] public Int16 biPlanes; [FieldOffset(14)] public Int16 biBitCount; [FieldOffset(16)] public Int32 biCompression; [FieldOffset(20)] public Int32 biSizeImage; [FieldOffset(24)] public Int32 biXPelsPerMeter; [FieldOffset(28)] public Int32 biYPelsPerMeter; [FieldOffset(32)] public Int32 biClrUsed; [FieldOffset(36)] public Int32 biClrImportant; [FieldOffset(40)] public Int32 colors; };
void AddPNGToImageList( ImageList il, string szFileName ) { Bitmap bm = new Bitmap( szFileName ); IntPtr hBitmap, ppvBits; BITMAPINFO bmi = new BITMAPINFO();
bmi.biSize = 40; bmi.biBitCount = 32; bmi.biPlanes = 1; bmi.biWidth = bm.Width; bmi.biHeight = bm.Height; hBitmap = CreateDIBSection( new IntPtr(0), bmi, 0, out ppvBits, new IntPtr(0), 0 ); BitmapData bitmapData; Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height ); bitmapData = bm.LockBits( rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); IntPtr pixels = bitmapData.Scan0; RtlMoveMemory( ppvBits, pixels, bm.Height*bitmapData.Stride ); bm.UnlockBits( bitmapData ); ImageList_Add( il.Handle, hBitmap, new IntPtr(0) ); }
|
|
|
| |
|
| |
| |
| Neal Andrews |
I have worked with the imagelist control but with the .net listview control.
The first thing is are you using a manifest For the imagelist to support 32bpp images you need a manifest file or call the following in .Net V1.1 Application.EnableVisualStyles Application.DoEvents '(More Bug fixes)
If the images are still not displayed correctly then it maybe that the images in the imagelist have lost there alpha channel (there are some bugs with the imagelist control, where the images loose there alpha channel at unexpected times when you add further images to the list.)
I have not used the ListView control yet so I cannot say how it is drawing the images. When drawing 32bpp images from the imagelist control you must use the Draw methods on the ImageList control and not the Draw Methods on the Graphics object for the alpha channel to be drawn correctly. Another problem with the ImageList control is that if you scale any images using the draw methods on the imagelist control then the alpha channel info is also lost. So you have to use the original win 32 api ImageList_DrawEx to draw the scaled images from the imagelist control. I have submitted this as a bug to MS, but as usual it's not a bug but a limitation (by design) of the imagelist control, which means it is a bug but MS are not prepared to fix it anytime soon.
Regards Neal
"Yuval Naveh" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
| |
| Yuval Naveh |
Neal, Thanks but your reply did not really help me. My problem is that ImageList when connected to any control (ListView, TreeView, ComboBox) will not show the image properly if the image as 256 levels in the alpha channel. The alpha pixels become opaque. I do not want to custom draw each element in each control, so Draw() method will not do the trick.
Any other ideas?
Yuval
"Neal Andrews" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... > I have worked with the imagelist control but with the .net listview control. [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Neal Andrews |
I have just had a look at the Listview control, and it handles my Images with Alpha transparency fine. Are you using Windows XP. Remember the use of the alpha channel in images is only supported in WindowsXP and above, which is why as I said, you have to call the EnableVisualStyles. I would also check that the alpha channel in your ImageList has not been corrupted by drawing a test image directly from the ImageList onto your form. If you still get the black areas then your images in your ImageList have lost there alpha channel information. Also the Images in the ImageList must be the same size as those displayed in the ImageList i.e. 16x16 for small icons. If they are scaled then they will not render correctly unless as I said you start handling the drawing of the images your self as the ImageList control does not scale images with alpha channel the ImageList control has a bug with scaling images (or as MS calls it, a limitation:).....)
Regards Neal
"Yuval Naveh" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
|
|
|
|
|
|
|