Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

HBITMAP Color->GrayScale

Posted on 2001-07-30
8
Medium Priority
?
1,334 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 

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 800 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
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…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…

596 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