Basically, I have code that retrieves icons, but all my attempts to convert
them to PixelFormat.Format32bppArgb Bitmaps loses the alpha information.
The goal is to have a method that will accept a file path and either a
background color or Bitmap on which to paint the shell icon, and return the
resulting pre-blended Bitmap. This will be used to show an Explorer-like
view of the server in a Web application.
public Bitmap ShellItemBitmap(string path, Color currentBackground);
public Bitmap ShellItemBitmap(string path, Bitmap currentBackground);
Thanks in advance,
M. Shawn Dillon
shawn....@insightbb.nospam.com
Senior Application Developer
MaximumASP, LLC.
It is easy, you can use memory streams and/or file io. You can even do
clipboard
operations with the CF_DIBV5 clipboard format.
Microsoft's knowledgebase has numerous articles on how to load and save
bitmap images. Most of the GDI API's accept the BITMAPV5HEADER
where you would normally use the BITMAPINFOHEADER.
The BITMAPV5HEADER is supported on Windows 2000, Windows XP and
Windows 2003 Server.
"M. Shawn Dillon" <shawn....@insightbb.moc> wrote in message
news:ukF31Kye...@TK2MSFTNGP11.phx.gbl...
To be fair, I'm rather new to the graphics APIs and don't understand many of
the terms yet, but I'm fairly proficient with using the Win32 APIs from C#.
I've found the
http://support.microsoft.com/default.aspx?scid=kb;en-us;318876 article that
describes how, in C++, to create an alpha-blended cursor or icon, so I'm
proceeding from that, but backwards (creating a bitmap from an icon).
1. Given an HICON, use GetIconInfo to grab HBITMAPs for the mask (does this
contain the alpha information?) and color info.
2. Create and fill out a BITMAPV5HEADER as in the above-referenced article.
2. Get a handle to a device context using GetDC.
3. Create a DIBSection(?) using CreateDIBSection that will allocate the
memory required to store the new bitmap data.
4. Here is where it breaks down. I'm not sure how to draw the HBITMAPs
returned from GetIconInfo onto the DIBSection, or how to convert the result
back into a managed System.Drawing.Bitmap...
Help! :)
Thanks again,
M. Shawn Dillon
shawn....@insightbb.nospam.com
Senior Application Developer
MaximumASP, LLC
"Michael Phillips, Jr." <m_phil...@nospam.hotmail.com> wrote in message
news:%23$82JN5eD...@TK2MSFTNGP11.phx.gbl...
Next you must set the alpha channel for each byte of the DIB. You must
extract
the alpha information from the handle to the mask bitmap.
Use:
BITMAP bmMask;
GetObject(hBitmapMask, sizeof(BITMAP), &bmMask);
This will give you access to the alpha bits. You can use the same code in
the article
to clear and set the alpha channel of the color DIBSection byte by byte.
Essentially, you now have an alpha formatted bitmap in a nice memory buffer.
Your next step is to create a System.Drawing.Bitmap with the same width and
height as your
icon but use PixelFormat32ARGB.
You now have an empty Bitmap that you must fill with the bits from your
DIBSection.
You will then have to use unsafe code to copy the DIBSection bits to your
new PixelFormat32ARGB Bitmap.
You use LockBits to access the Scan0 field of the BitmapData structure and
the copy each scanline
from the DIBSection bitmap to your gdi+ bitmap. Both have the same stride,
PixelFormat and image size
so you may copy the whole DIBSection image to your gdi+ bitmap rather than
copy a scanline at a time
I hope this helps.
"M. Shawn Dillon" <shawn....@insightbb.moc> wrote in message
news:uzz$g0LfDH...@TK2MSFTNGP12.phx.gbl...
I have an easier solution for you.
1) Create a System.Drawing.Bitmap with the same width and height of the icon
but use PixelFormat32ARGB. This will give you an empty bitmap that you
need to fill with the bits of the icon.
2) Grab the hbmColor and hbmMask from the iconinfo structure.
3) Create a Gdiplus Graphics object from the new System.Drawing.Bitmap that
you created in Step1.
4) Create a System.Drawing.Bitmap from the hbmColor handle.
5) Use DrawImage to copy the bmColor Bitmap from Step 4 to the bitmap
created in Step 1. You now have the color bits set correctly.
Dispose of the Graphics object.
6) Use the following to gain access to the Icon's Mask:
BITMAP bmMask;
GetObject(hbmMask, sizeof(BITMAP), &bmMask);
Each pixel is either a 0 or a 1 representing an alpha of 0 or 255.
There are 8 pixels packed into each byte.
7) Use unsafe LockBits to gain access the color bitmap bits.
Now clear and/or set the Alpha Channel.
for ( int i = 0; i < bmData.Height; i++)
{
// Color portion of the Icon
unsigned int* Bits = (unsigned int*)bmData.Scan0 + (
bmData.Height - 1 - i) * bmData.Stride;
// For a 1bpp Mask there are 8 pixels packed into 1 byte
// Each pixel is an index into a color palette. In this case the
index represents 0 or 255
unsigned char* MaskBits = (unsigned char*)bmMask.bmBits +
(bmMask.bmHeight - 1 - i) * bmMask.bmWidthBytes;
int col = 0;
for ( int j = 0; j < bmData.Width; j++ )
{
ARGB color = Bits[j];
// grab the alpha from the Icon Mask
unsigned char Alpha = ( (*MaskBits << col ++) & 0x80 ) ?
255 : 0 ;
// Set or clear the alpha channel
Bits[j] = Color::MakeARGB(Alpha, color.GetRed(),
color.GetBlue(), color.GetGreen());
if ( ! (col % 8) ) // when all 8 pixel read, advance to
the next pixel
MaskBits++;
}
}
Since I haven't tested this code, make sure that you don't cross the Icon
Mask's scanline.
The Width of the Mask's Bitmap represents pixels. There should be (Width >>
3) bytes
in each scanline.
"Michael Phillips, Jr." <m_phil...@nospam.hotmail.com> wrote in message
news:Ojo%23ipTf...@TK2MSFTNGP12.phx.gbl...
I lost track over what you are trying to accomplish.
To preserve the alpha channel, you must use the technique outlined in the
article using
a BITMAPV5HEADER. Gdi+ will load an icon in PixelFormat32bppARGB.
Gdi+ converts everything internally to 32bpp. By design it will only save
to the PNG
format as there is no encoder for icons. Any bitmap image with an alpha
channel
will lose the alpha channel when loaded or saved, unless you use your own
encoder/decoder.
Getting a handle to the Icon that Gdi+ produces and using it to get an
ICONINFO
structure will leave you disappointed. I tried to get BITMAP info from the
handles
to the color and mask bitmaps. The information returned does not give you
access
to the bits. That field is null!
I believe you need to roll your own encoder/decoder if you wish to work with
all icon formats and all bitmap formats . That is why I suggest the
following article:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_icons.asp
It includes a sample application that will help you understand the icon
format and provides
links to other articles about DIB's and Bitmap's. With the information
outlined in these
articles, you should have no trouble creating a really usefull
encoder/decoder for bitmaps
and icons supporting all color formats.
Using the BITMAPV5HEADER and CreateDIBSection API's, You should be able to
create bitmaps
with color formats ranging from 1bpp to 64bpp. By using Gdi+, you can
convert between the other
image formats supported and your enhanced bitmap and icon encoder/decoder.
"Michael Phillips, Jr." <m_phil...@nospam.hotmail.com> wrote in message
news:OsRsiLX...@tk2msftngp13.phx.gbl...
Thank you! This is exactly what I needed.
"Michael Phillips, Jr." <m_phil...@nospam.hotmail.com> wrote in message
news:Ojo#ipTfD...@TK2MSFTNGP12.phx.gbl...