|
-
February 20th, 2008, 07:41 AM
#1
Help copying HBITMAP from file to new HBITMAP
I am trying to load a .bmp into an HBITMAP and then copy a portion of it into a new memory HBITMAP. I am pretty familiar with device contexts, memory bitmaps, and GDI - but I think I am missing something about HBITMAP creation. I've read and reread everything on the net but nothing has a complete code sample for this simple task so my efforts have been futile.
The following code (simplified) produces black squares on the screen - what am I missing?
//first load the source bitmap from a file - this works fine and will print to
// the screen with no problem
HBITMAP hbmsource = (HBITMAP)LoadImage(NULL,filepath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//get the screen device context
CDC* pDC = GetDC();
//create two memory dcs compatible with the screen
HDC memDCsource = CreateCompatibleDC(pDC->m_hDC);
HDC memDCtarget= CreateCompatibleDC(pDC->m_hDC);
//select the source bitmap into the source DC
HBITMAP pOldBitmap1 = (HBITMAP)SelectObject(memDCsource,hbmsource);
//create a new bitmap compatible with the screen dc
HBITMAP hbmtarget = CreateCompatibleBitmap(pDC->m_hDC,w,h);
//.....I suspect that I am missing something here required to create the new
// bitmap... ie bitmap header, CreateDIB, etc. - I thought that CreateCompatibleBitmap
//covered all that.....
//select the new bitmap into the target dc
HBITMAP pOldBitmap2 = (HBITMAP)SelectObject(memDCtarget,hbmtarget);
//bitblt the source to the target
BitBlt(memDCtarget,0,0,w,h,memDCsource,0,0,SRCCOPY);
//cleanup
SelectObject(memDCsource,pOldBitmap1);
SelectObject(memDCtarget,pOldBitmap2);
DeleteDC(memDCsource);
DeleteDC(memDCtarget);
ReleaseDC(pDC);
.......Now when I try and display the new HBITMAP on the screen it is all black.
thanks for any help
-
February 20th, 2008, 12:09 PM
#2
Re: Help copying HBITMAP from file to new HBITMAP
 Originally Posted by jreck2112
//create a new bitmap compatible with the screen dc
HBITMAP hbmtarget = CreateCompatibleBitmap(pDC->m_hDC,w,h);
.......Now when I try and display the new HBITMAP on the screen it is all black.
Try to create your hbmtarget compatible to memDCsource (after you have selected source bitmap into it).
Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
Convenience and productivity tools for Microsoft Visual Studio:
FeinWindows - replacement windows manager for Visual Studio, and more...
-
February 20th, 2008, 01:01 PM
#3
Re: Help copying HBITMAP from file to new HBITMAP
or try to make the loaded bitmap compatible.
MSDN states that LoadImage makes it compatible but
you should see what works in action.
to test/debug try to BitBlt onto the screen ( a display DC ) to
see if the loaded image does appear correctly ( i.e. it is
loaded and compatible ).
-
February 21st, 2008, 03:15 AM
#4
Re: Help copying HBITMAP from file to new HBITMAP
Use GDI+. It is much simpler to use than GDI. Below is the code for cropping the image and saving them. If you do not want to save, just commented the Save function in CropImage().
Code:
using namespace Gdiplus;
void Test()
{
Bitmap SrcBmp(L"E:\\Hello.jpg", TRUE);
bool bRet = CropImage(
SrcBmp,
160,
35,
510,
490,
L"E:\\Hello2.jpg",
L"image/jpeg" );
if( bRet )
MessageBox(L"Successful");
else
MessageBox(L"Failed");
}
bool CropImage(
Bitmap &SrcBmp,
int x,
int y,
int nWidth,
int nHeight,
const std::wstring& szDestFile,
const std::wstring& szEncoderString )
{
Rect rect(x, y, nWidth, nHeight);
Bitmap* pDestBmp = SrcBmp.Clone(rect, PixelFormatDontCare);
if( !pDestBmp )
return false;
CLSID Clsid;
int result = GetEncoderClsid(szEncoderString.c_str(), &Clsid);
if( result < 0 )
return false;
Status status = pDestBmp->Save( szDestFile.c_str(), &Clsid );
delete pDestBmp;
pDestBmp = NULL;
return status == Ok;
}
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
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 -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
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 j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
If you want to display the cropped image, just use the code below,
Code:
Graphics graphics(hDC);
graphics.DrawImage(pDestBmp,0,0,nWidth,nHeight);
Last edited by CBasicNet; February 21st, 2008 at 03:21 AM.
-
February 21st, 2008, 03:20 AM
#5
Re: Help copying HBITMAP from file to new HBITMAP
If the OP only wants to display the cropped image, here is the edited code.
Code:
bool CropImage(
Bitmap &SrcBmp,
int x,
int y,
int nWidth,
int nHeight,
const std::wstring& szDestFile,
const std::wstring& szEncoderString )
{
Rect rect(x, y, nWidth, nHeight);
Bitmap* pDestBmp = SrcBmp.Clone(rect, PixelFormatDontCare);
if( !pDestBmp )
return false;
Graphics graphics(hDC);
graphics.DrawImage(pDestBmp,0,0,nWidth,nHeight);
delete pDestBmp;
pDestBmp = NULL;
return status == Ok;
}
Remember to include the Gdiplus.h and link to Gdiplus.lib
-
February 26th, 2008, 09:28 AM
#6
Re: Help copying HBITMAP from file to new HBITMAP
Thanks for the suggestions....
- I had tried making the CDC compatible with the source DC but that did not make a difference (and in past experiences, had made things worse).
- The loaded images were working fine standalone (and could be succesfully displayed on the screen).
- I'd love to switch to GDI+ but haven't explored yet the easiest way to use with C++ (i.e. VC6) - can't bring myself to jump into C# yet.
BOTTOM LINE - the problem turned out to be quite fundamental... I wasn't allocating any memory for the new target bitmap. It was properly compatible and coded correctly, but without the Alloc - nowhere to put all the pretty pixels.
Thanks for the help.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|