Solved

HBITMAP Color->GrayScale

Posted on 2001-07-30
8
1,260 Views
Last Modified: 2013-12-03
Hi, How do I convert a HBITMAP in Colors to GrayScale, or black & white bitmap ?

CB.
0
Comment
Question by:win32
  • 5
  • 3
8 Comments
 

Author Comment

by:win32
ID: 6333741
Please people, I am waiting for your answer!
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 6333886
Hi win32,

to simply convert it you can create a DDB as shown at http://www.codeguru.com/bitmap/dib_to_ddb.shtml ... this code uses MFC but it shouldn't be too hard to do the same in pure Win32 API.

Other helpful link maybe this: http://www.codeguru.com/bitmap/ChangingColorDepth.html

hope that helps,

ZOPPO
0
 

Author Comment

by:win32
ID: 6333976
What I realy need is somthing like a LoadDIImage() function, how is that made ?
0
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 

Author Comment

by:win32
ID: 6334004
Can't you mail me the code at codeguro man, my internet Cant connect to the site at the moment...

cb_priv@hotmail.com
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 200 total points
ID: 6334048
This is from http://www.codeguru.com/bitmap/dib_to_ddb.shtml :
-----------------------------------------------------------------------------------------------------------------
You can render a device-independent bitmap (DIB) onto a device without having to convert it into a device-dependent bitmap (DDB). However, the
                      process is slower when using a DIB and you also don't have access to few very versatile functions such as BitBlt() which handle only DDBs.

                      The basic steps involved in creating a device-dependent bitmap from a device-independent bitmap are:

                        1.Create a logical palette from the information in the DIB color table. You need to do this only if the device supports palettes. To create the palette,
                           allocate enough memory for a LOGPALETTE structure with memory for the color table as well. Initialize the palVersion and palNumEntries fields
                           and copy the color values from the color table in the DIB. Then call CreatePalette() using the LOGPALETTE structure we initialized.
                        2.Select the logical palette into the device for which we are creating the DDB, then realize the palette.
                        3.Create the DDB using the CreateDIBitmap() function.
                        4.Don't forget to release any memory allocated for the LOGPALETTE structure.

                      Although this function creates a logical palette, it doesn't return this information to the calling code. If the DIB represents a 256 color bitmap and the device
                      supports only 256 colors, then rendering the DDB onto the device will probably not result in the proper image. That's because the system palette colors may
                      not match the colors that are being used by the bitmap. You may, therefore, want to modify the function so that it returns the logical palette as well. You
                      would have to select and realize this palette onto the device context before drawing the bitmap image.


                      HBITMAP DIBToDDB( HANDLE hDIB )
                      {
                              LPBITMAPINFOHEADER      lpbi;
                              HBITMAP                 hbm;
                              CPalette                pal;
                              CPalette*               pOldPal;
                              CClientDC               dc(NULL);

                              if (hDIB == NULL)
                                      return NULL;

                              lpbi = (LPBITMAPINFOHEADER)hDIB;

                              int nColors = lpbi->biClrUsed ? lpbi->biClrUsed :
                                                                      1 << lpbi->biBitCount;

                              BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
                              LPVOID lpDIBBits;
                              if( bmInfo.bmiHeader.biBitCount > 8 )
                                      lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
                                              bmInfo.bmiHeader.biClrUsed) +
                                              ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
                              else
                                      lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);

                              // Create and select a logical palette if needed
                              if( nColors <= 256 && dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
                              {
                                      UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
                                      LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

                                      pLP->palVersion = 0x300;
                                      pLP->palNumEntries = nColors;

                                      for( int i=0; i < nColors; i++)
                                      {
                                              pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
                                              pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
                                              pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
                                              pLP->palPalEntry[i].peFlags = 0;
                                      }

                                      pal.CreatePalette( pLP );

                                      delete[] pLP;

                                      // Select and realize the palette
                                      pOldPal = dc.SelectPalette( &pal, FALSE );
                                      dc.RealizePalette();
                              }

                             
                              hbm = CreateDIBitmap(dc.GetSafeHdc(),           // handle to device context
                                              (LPBITMAPINFOHEADER)lpbi,       // pointer to bitmap info header
                                              (LONG)CBM_INIT,                 // initialization flag
                                              lpDIBBits,                      // pointer to initialization data
                                              (LPBITMAPINFO)lpbi,             // pointer to bitmap info
                                              DIB_RGB_COLORS );               // color-data usage

                              if (pal.GetSafeHandle())
                                      dc.SelectPalette(pOldPal,FALSE);

                              return hbm;
                      }
-----------------------------------------------------------------------------------------------------------------

The other one can be downloaded from http://www.codeguru.com/bitmap/ChangingColorDepth_src.zip ... if you can't donwload it either you can post me your email and I send you the zip-file as attachement.

ZOPPO
0
 

Author Comment

by:win32
ID: 6337254
That might work fine. I wanna explain my problem more carefully!
My problem is that I want to print a color bitmap. Naturaly my SelectObject function failes if I try to print the color bitmap to a printer that don't have color support. That is a problem, I am not realy sure of the best way to solve the problem so I'll give you my code, then hopfully you can tell me:

I get a DC from the printer when i init the PrintDialog

CODE LOKKS LIKE THIS:
...

BOOL PrintBitMap(HDC hdcPrinter)
HBITMAP hbmp, holdbmp;
BITMAP bm;
HDC hMemDC;

if (hdcPrinter)// hdc from the printer
 hMemDC = CreateCompatibleDC(hdcPrinter);
hbmp = (HBITMAP) LoadImage(hInstPrint,
              MAKEINTRESOURCE(iResID),
           IMAGE_BITMAP,                                 iResW,
           (iResH == -1 ? iH : iResH),
            LR_CREATEDIBSECTION);

// The LoadBmp has always success
if (hbmp != NULL)
  {
    GetObject(hbmp, sizeof(BITMAP), (LPSTR)&bm);
    holdbmp = (HBITMAP)SelectObject(hMemDC, hbmp);
/* SelectObject failes if the DC for the printer and the Bitmap does not fit. That is the problem, printer HDC can't alwayes take my bitmap!! */

    StretchBlt(hdcContext, X, Y, iW*iS*iFontScale,
                                 iH*iS*iFontScale,
                                 hMemDC,
                     iW*iI,                                0,
                     iW,                                     iH,                                     SRCCOPY);  
         
    DeleteDC(hMemDC);
    DeleteObject(hbmp);

    return true;
  }
  DeleteDC(hMemDC);

  return false;
}
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 6339946
Well, you can try to create the memDC as not compatible to the printerDC but i.e. to a temporary created, none-monochrome ScreenDC or a TrueColorDC, since StretchBlt will convert the colors/bitsPerPixel as needed.
0
 

Author Comment

by:win32
ID: 6407208
Ok, you are telling me that HDC's can't alwayes take BMP's How do I know that, Can you tell me how I can see if a HDC can take a bitmap ?
0

Featured Post

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
error email attachment VB2010 5 46
Having Trouble with MS Access 2010 CommandBars 19 106
Visual Studio Debugging 3 140
Which Microsoft MSDN Package Is The One I need? 3 48
This article surveys and compares options for encoding and decoding base64 data.  It includes source code in C++ as well as examples of how to use standard Windows API functions for these tasks. We'll look at the algorithms — how encoding and decodi…
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question