
|
[shell-coding] Re: Gdi+ and XP Icons -- A Solution
- From: Hollow <hollow1@xxxxxxxxxxxxx>
- To: shell-coding@xxxxxxxxxxxxx
- Date: Fri, 13 May 2005 02:53:17 -0400
Never mind. It seems that DrawIconEx actually places the alpha channel
information in the unused channel of the bitmap if you use a 32-bit bitmap.
So you don't have to calculate this, its given to you. So adding it to the
Gdi+ bitmap becomes trivial.
Still doesn't explain why I couldn't find any reference to this online or
why Gdi+ doesn't pick it up.
Eric
-----Original Message-----
From: shell-coding-bounce@xxxxxxxxxxxxx
[mailto:shell-coding-bounce@xxxxxxxxxxxxx] On Behalf Of Hollow
Sent: Wednesday, May 11, 2005 7:20 PM
To: shell-coding@xxxxxxxxxxxxx
Subject: [shell-coding] Re: Gdi+ and XP Icons -- A Solution
I chose A and a. I know B and C from the icon (B) and the icon blended
over A-a (C).
I want b (the alpha channel of the icon) so that I can use the icon like any
other bitmap in Gdi+.
At first glance it looks like the Bitmap constructor that takes an HICON
should work for this, but it doesn't bring in the alpha channel. So this is
a way to get it.
Eric
-----Original Message-----
From: shell-coding-bounce@xxxxxxxxxxxxx
[mailto:shell-coding-bounce@xxxxxxxxxxxxx] On Behalf Of bill barry
Sent: Wednesday, May 11, 2005 6:30 PM
To: shell-coding@xxxxxxxxxxxxx
Subject: [shell-coding] Re: Gdi+ and XP Icons -- A Solution
why are you trying to get b? I thought you chose a, A, b, and B.
On 5/8/05, Hollow <hollow1@xxxxxxxxxxxxx> wrote:
> I've been working with Gdi+ recently and is poor handling of XP icons has
> been by far the most irksome aspect of it. I got to thinking about this
> today, and came up with the following idea.
>
> At its most basic level, compositing a pixel with an alpha channel onto a
> pixel with an alpha channel works as follows:
>
> C = bB + (1-b)aA
>
> Where C is the composite color obtained by placing a pixel with color B
and
> alpha b over a pixel with color A and alpha a. (This equation is valid on
> the range [0, 1], and is applied to each channel of the color.)
>
> Working with an icon one has access to B and C, and can chose A and a.
This
> is adequate information to back calculate b. Selecting A and a as 255 and
> 255 and plugging into the equation results in:
>
> b = (C-1)/(B-1)
>
> This back calculation is carried out by the extremely rough code at the
end.
>
> The question this leaves me with is the following, why doesn't Gdi+ do
this
> and why couldn't I find this on Google? Is there a better way--why
> shouldn't I do this?
>
> Currently my code to draw an icon onto a Gdiplus::Bitmap is horrendous,
but
> it works. This seems like an ideal replacement to me.
>
> Eric
>
> // CODE -----------------------------------------
> #include <iostream>
> #include <windows.h>
> #include <math.h>
> #include <gdiplus.h>
> using namespace std;
>
> bool GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
> {
> using namespace Gdiplus;
> UINT num = 0; // number of image encoders
> UINT size = 0; // size of the image encoder
> array in bytes
>
> ImageCodecInfo* pImageCodecInfo = NULL;
>
> GetImageEncodersSize(&num, &size);
> if(size == 0)
> return false; // no codecs installed.
>
> pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
> if(pImageCodecInfo == NULL)
> return false; // out of memory
>
> GetImageEncoders(num, size, pImageCodecInfo);
>
> for(UINT j = 0; j < num; ++j)
> {
> if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
> {
> *pClsid = pImageCodecInfo[j].Clsid;
> free(pImageCodecInfo);
> return true; // Success
> }
> }
>
> free(pImageCodecInfo);
> return false; // codec doesn't exist
> }
>
> int main()
> {
> class UsingGdiplus
> {
> public:
> UsingGdiplus()
> {
> Gdiplus::GdiplusStartupInput gpsi;
> Gdiplus::GdiplusStartup(&token, &gpsi, NULL);
> }
> ~UsingGdiplus() { Gdiplus::GdiplusShutdown(token); }
> private:
> ULONG_PTR token;
> } ugp;
>
> HICON ico = 0;
> if(ExtractIconEx("c:\\windows\\system32\\shell32.dll",3, &ico, 0,
1)
> != 1)
> {
> cout << "extraction failed" << endl;
> exit(0);
> }
>
> BITMAPINFOHEADER bmpInfo32;
> bmpInfo32.biSize = sizeof(BITMAPINFOHEADER);
> bmpInfo32.biWidth = 32;
> bmpInfo32.biHeight = 32;
> bmpInfo32.biPlanes = 1;
> bmpInfo32.biBitCount = 24;
> bmpInfo32.biCompression = BI_RGB;
> bmpInfo32.biSizeImage = 0;
> bmpInfo32.biXPelsPerMeter = 0;
> bmpInfo32.biYPelsPerMeter = 0;
> bmpInfo32.biClrUsed = 0;
> bmpInfo32.biClrImportant = 0;
>
> DWORD* bits;
>
> HDC dc = CreateCompatibleDC(0);
> HBITMAP bmp = CreateDIBSection(dc, (BITMAPINFO*)&bmpInfo32,
> DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
> if(!bmp)
> {
> cout << "creating dibsection failed" << endl;
> DeleteDC(dc);
> DestroyIcon(ico);
> exit(0);
> }
> HBITMAP hbOld = (HBITMAP)SelectObject(dc,bmp);
>
> HBRUSH brush = CreateSolidBrush(RGB(0xff,0xff,0xff));
> DrawIconEx(dc, 0, 0, ico, 0, 0, 0, brush, DI_NORMAL);
> DeleteObject(brush);
>
> Gdiplus::Bitmap gpb(ico);
> DestroyIcon(ico);
>
> for(int i = 0; i < 32; ++i)
> {
> for(int j = 0; j < 32; ++j)
> {
> Gdiplus::Color gpc;
> gpb.GetPixel(i,j,&gpc);
> COLORREF B = gpc.ToCOLORREF();
> COLORREF C = GetPixel(dc,i,j);
> if(B != C && C != RGB(0xff,0xff,0xff))
> {
> double Br = (double)(GetRValue(B)-255);
> double Bg = (double)(GetGValue(B)-255);
> double Bb = (double)(GetBValue(B)-255);
> double Cr = (double)(GetRValue(C)-255);
> double Cg = (double)(GetGValue(C)-255);
> double Cb = (double)(GetBValue(C)-255);
>
> int alpha = (int)((floor(255*Cr/Br) +
> floor(255*Cg/Bg) + floor(255*Cb/Bb))/3.0);
> gpb.SetPixel(i,j, Gdiplus::Color(alpha,
> gpc.GetR(), gpc.GetG(), gpc.GetB()));
> }
> }
> }
> bmp = (HBITMAP)SelectObject(dc, hbOld);
> DeleteObject(bmp);
> DeleteDC(dc);
>
> CLSID pngClsid;
> GetEncoderClsid(L"image/png", &pngClsid);
> gpb.Save(L"g:\\fixed.png", &pngClsid);
> return 0;
> }
>
> __________________________________________________
> Subscription options and archive:
> http://www.freelists.org/list/shell-coding
>
>
__________________________________________________
Subscription options and archive:
http://www.freelists.org/list/shell-coding
__________________________________________________
Subscription options and archive:
http://www.freelists.org/list/shell-coding
__________________________________________________
Subscription options and archive:
http://www.freelists.org/list/shell-coding
Other related posts:[shell-coding] Gdi+ and XP Icons -- A Solution [shell-coding] Re: Gdi+ and XP Icons -- A Solution [shell-coding] Re: Gdi+ and XP Icons -- A Solution [shell-coding] Re: Gdi+ and XP Icons -- A Solution
|

|

|
[ Home |
Signup |
Help |
Login |
Archives |
Lists
]
All trademarks and copyrights within the FreeLists archives are owned
by their respective owners. Everything else ©2008 Avenir Technologies, LLC.
|

|
|