Перенос изображения с CDC на CBitmap

Как я могу перенести изображение с CDC на CBitmap?
Проблема в целом:
У меня есть большое изображение в CBitmap A. Мне нужно перенести части этого изображения в число CBitmap для хранения в вектор, потому что я не могу использовать несколько CDC для этого 🙂
Я превращаю подготовленный CDC в цикл (получаю необходимую часть CBitmap A) и затем мне нужно перенести его в CBitmap x.
Как мне это сделать?

Вот мой код:

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);

// Все нормально — у меня есть исходная картинка

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);

// У меня здесь черные квадраты! — что-то не так с предыдущим кодом

        m_bitmaps.push_back(destBitmap);

destDC.SelectObject(oldBitmap);
}

bmpWhole.DeleteObject();
destDC.DeleteDC();
SourceDC.DeleteDC();

// А позже CBitmaps — черные квадраты


Я нашел решение!

Разбор CBitmap и инициализация вектора

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();

Рисовать:

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);
}

2

Решение

Создайте другой контекст устройства и по одному создайте и выберите в нем целевые растровые изображения и используйте BitBlt скопировать части исходного изображения в них. Ниже приведен пример того, как вы могли бы сделать это.

// 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);
}

Я упустил проверку ошибок для простоты. Если вы используете C ++ 11 или Boost, я рекомендую использовать unique_ptr управлять временем жизни растрового объекта. В противном случае вам нужно delete это в соответствующем месте, таком как деструктор.

1

Другие решения

Других решений пока нет …