Reputation: 45
How can I transfer an image from CDC to CBitmap? The problem in whole: I have a big image into CBitmap A. I need to transfer parts of this image to a number of CBitmap for the storage into a vector, because I can't use a number of CDC for this :) I make a prepared CDC into a cycle (get a neccessary part of CBitmap A) and then I need to transfer it to CBitmap x. How can I do it?
Here's my code:
m_bitmaps.clear();
m_bitmaps.reserve(4);
CDC SourceDC, destDC;
SourceDC.CreateCompatibleDC(pMainDC);
destDC.CreateCompatibleDC(pMainDC);
CBitmap bmpWhole; // bmp 200*200
bmpWhole.LoadBitmap(IDB_TEST_BITMAP);
SourceDC.SelectObject(&bmpWhole);
//pMainDC->BitBlt(0,0,200,200,&SourceDC,0,0,SRCCOPY);
// It's OK - I got a source picture
for (int x=100; x>=0; x-=100)
for (int y=100; y>=0; y-=100)
{
CBitmap *destBitmap = new CBitmap();
destBitmap->CreateCompatibleBitmap(&destDC, 100, 100);
CBitmap *oldBitmap = destDC.SelectObject(destBitmap);
destDC.BitBlt(0,0,100,100,&SourceDC,x,y,SRCCOPY);
pMainDC->BitBlt(x*1.1,y*1.1,100,100,&destDC,0,0,SRCCOPY);
// I got black squares here! - something wrong with previous code
m_bitmaps.push_back(destBitmap);
destDC.SelectObject(oldBitmap);
}
bmpWhole.DeleteObject();
destDC.DeleteDC();
SourceDC.DeleteDC();
// And later CBitmaps are black squares
I found the solution!
Parsing the CBitmap and initializing the vector
m_bitmaps.clear();
m_bitmaps.reserve(4);
CDC SourceDC, destDC;
SourceDC.CreateCompatibleDC(pMainDC);
CBitmap bmpWhole;
bmpWhole.LoadBitmap(IDB_TEST_BITMAP);
SourceDC.SelectObject(&bmpWhole);
for (int x=100; x>=0; x-=100)
for (int y=100; y>=0; y-=100)
{
CImage *destImage = new CImage();
destImage->Create(100, 100, 24);
destDC.Attach(destImage->GetDC());
destDC.BitBlt(0,0,100,100,&SourceDC,x,y,SRCCOPY);
destDC.Detach();
destImage->ReleaseDC();
m_bitmaps.push_back(destImage);
}
bmpWhole.DeleteObject();
destDC.DeleteDC();
SourceDC.DeleteDC();
Draw:
WORD nShift=0;
for (auto iter = m_bitmaps.begin(); iter != m_bitmaps.end(); ++iter, nShift+=110)
{
CBitmap* pBitmap = CBitmap::FromHandle((*iter)->operator HBITMAP());
CDC memDC;
memDC.CreateCompatibleDC(pMainDC);
memDC.SelectObject(pBitmap);
pMainDC->BitBlt(nShift, 0, 100, 100, &memDC, 0, 0, SRCCOPY);
}
Upvotes: 2
Views: 5883
Reputation: 20103
Create another device context and one by one create and select your target bitmaps into it and use BitBlt
to copy portions of the source bitmap into them. Below is an example of how you might do this.
// Create a DC compatible with the display
// this is used to copy FROM the source bitmap
sourceDC.CreateDC(NULL);
sourceDC.SelectObject(&sourceBitmap);
// Create another device context for the destination bitmap
destDC.CreateCompatibleDC(&sourceDC);
for(int i = 0; i < numBitmaps; i++)
{
// Determine the x, y, sourceX, sourceY, with and height here
// ...
// create a new bitmap
CBitmap *destBitmap = new CBitmap();
destBitmap->CreateCompatibleBitmap(&destDC, width, height);
// Select the bitmap into the destination device context
CBitmap *oldBitmap = destDC.SelectObject(destBitmap);
// copy the bitmap
destDC.BitBlt(x, y, width, height, &sourceDC, sourceX, sourceY, SRCCOPY);
// add it to the vector
bitmapVector.push_back(destBitmap);
// Clean up
destDC.SelectObject(oldBitmap);
}
I omitted error checking for simplicity. If you are using C++11 or Boost I recommend using unique_ptr
to manage the lifetime of the bitmap object. Otherwise you need to delete
it at the appropriate place such as the destructor.
Upvotes: 1