Solved

HBITMAP Color->GrayScale

Posted on 2001-07-30
8
1,251 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
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 

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

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
DataAdapter, stored procedures and parameters 2 48
Get the most recent file to copy into a sql table with ssis 2 103
Problem to open text file 11 107
VS2015 Redefinition errors 4 49
This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
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…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

785 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