Go to the FreeLists Home Page Home Signup Help Login
 



Browse shell-coding: This Month's ArchiveMain Archive PageRelated postsPrevious by DateNext by Date

[shell-coding] Re: Gdi+ and XP Icons -- A Solution

  • From: bill barry <after.fallout@xxxxxxxxx>
  • To: shell-coding@xxxxxxxxxxxxx
  • Date: Wed, 11 May 2005 18:30:22 -0400
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

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.