Двойная буферизация изображения с помощью GDI +

У меня есть изображение (.png), хранящееся внутри типа данных GDI + Image. Может кто-нибудь сказать мне, как я хотел бы получить данные изображения, хранящиеся в переменной изображения GDI +, внутри DC памяти?

Вот некоторый код:

Graphics graphics(hdc);
Image image(pStream);

int image_width;
int image_height;

image_width= image.GetWidth();
image_height=image.GetHeight();

graphics.DrawImage(&image, posX,posY, image_width, image_height);

Цель состоит в том, чтобы иметь возможность дважды буферизовать это изображение GDI + (ради анимации!).

Я знаю, как двойной буфер с GDI, но не с GDI +. С GDI просто выберите HBITMAP в DC памяти, однако, с GDI +, изображение находится не в HBITAP, а, скорее, в переменной изображения. Может кто-нибудь сказать мне, как получить изображение, которое не является HBITMAP, в DC памяти? Спасибо.

0

Решение

Вот код, который я использую для загрузки изображений с диска.

// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF
HBITMAP mLoadImg(WCHAR *szFilename)
{
HBITMAP result=NULL;

Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(szFilename,false);
bitmap->GetHBITMAP(NULL, &result);
delete bitmap;
return result;
}

Редактировать:
Не используйте GDI + сам, кроме как для нескольких основных функций. Всякий раз, когда я использую изображения, я обычно хочу наименьший, самый быстрый код из возможных — GDI лучше справляется с этой задачей.

А вот код, извлеченный из класса, который будет отображать изображение с прозрачными пикселями, дополненное определением класса, чтобы (надеюсь) избежать двусмысленности с переменными класса.

void CStaticImg::displayImage()
{
RECT myRect;
BITMAP bm;
HDC screenDC, memDC;
HBITMAP oldBmp;
BLENDFUNCTION bf;

GetObject(mBmp, sizeof(bm), &bm);

bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xff;

bf.AlphaFormat = AC_SRC_ALPHA;

screenDC = GetDC(mHwnd);
GetClientRect(mHwnd, &myRect);

if (mBmp == NULL)
FillRect(screenDC, &myRect, WHITE_BRUSH);

else
{
memDC = CreateCompatibleDC(screenDC);
oldBmp = (HBITMAP)SelectObject(memDC, mBmp);
AlphaBlend (screenDC, 0, 0, myRect.right,myRect.bottom, memDC, 0, 0, bm.bmWidth,bm.bmHeight, bf);
SelectObject(memDC, oldBmp);
DeleteDC(memDC);
ReleaseDC(mHwnd, screenDC);
}
}

class CStaticImg
{
public:
CStaticImg();
~CStaticImg();
void setImg(HBITMAP img);
HBITMAP getImgCopy();
void attach(HWND tgt);
void detach();
void setBkMode(bool transparent);

protected:
HWND mHwnd;
HBITMAP mBmp;
WNDPROC mOldWndProc;
void displayImage();
virtual LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
bool isBkgTransparent;
private:
//    virtual LRESULT onPaint();
LRESULT onCreate();
static CStaticImg *GetObjectFromWindow(HWND hWnd);
static LRESULT CALLBACK stWinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
0

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

Вы смотрели на Bitmap учебный класс? Он наследуется от Image и может быть использован для получения доступа к необработанным данным изображения:

Bitmap bmp(pStream);
BitmapData bitmapData;
Rect rect(0, 0, 200, 200);
// lock area of the image for writing
bmp.LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData);

Обновить Чтобы получить HBITMAP, можно использовать что-то подобное (ПРИМЕЧАНИЕ: я не проверял приведенный ниже код):

   HBITMAP hbmp = CreateCompatibleBitmap(hdc, width, height);
BITMAPINFO bmi;
bmi.bmiHeader.biSize =  sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiColors = NULL;

SetDIBits(hdc, hbmp, 0, height,  bitmapData.Scan0, &bmi, 0);
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector