Solved

HBITMAP Color->GrayScale

Posted on 2001-07-30
8
1,231 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 30

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
 

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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 30

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 30

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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

758 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now