Как обновить созданный пользователем Bitmap в Windows API - PullRequest
2 голосов
/ 01 января 2011

В своем коде я быстро генерирую изображения на лету и хочу отображать их как можно быстрее.Поэтому в первый раз, когда я создаю свой образ, я создаю новый BITMAP, но вместо того, чтобы удалять старый и создавать новый для каждого последующего изображения, я просто хочу скопировать свои данные обратно в существующий.Вот мой код для первоначального создания и обновления.Создание работает просто отлично, но обновление не работает.

BITMAPINFO bi;
HBITMAP Frame::CreateBitmap(HWND hwnd, int tol1, int tol2, bool useWhite, bool useBackground)
{
  ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
  bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  bi.bmiHeader.biWidth = width;
  bi.bmiHeader.biHeight = height;
  bi.bmiHeader.biPlanes = 1;
  bi.bmiHeader.biBitCount = 24;
  bi.bmiHeader.biCompression = BI_RGB;
  ZeroMemory(bi.bmiColors, sizeof(RGBQUAD));

  // Allocate memory for bitmap bits
  int size = height * width;
  Pixel* newPixels = new Pixel[size];

  // Recompute the output
  //memcpy(newPixels, pixels, size*3);
  ComputeOutput(newPixels, tol1, tol2, useWhite, useBackground);

  HBITMAP bitmap = CreateDIBitmap(GetDC(hwnd), &bi.bmiHeader, CBM_INIT, newPixels, &bi, DIB_RGB_COLORS);
  delete newPixels;

  return bitmap;
}

и

void Frame::UpdateBitmap(HWND hwnd, HBITMAP bitmap, int tol1, int tol2, bool useWhite, bool useBackground)
{
  ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
  bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

  HDC hdc = GetDC(hwnd);
  if(!GetDIBits(hdc, bitmap, 0, bi.bmiHeader.biHeight, NULL, &bi, DIB_RGB_COLORS))
    MessageBox(NULL, "Can't get base image info!", "Error!", MB_ICONEXCLAMATION | MB_OK);

  // Allocate memory for bitmap bits
  int size = height * width;
  Pixel* newPixels = new Pixel[size];

  // Recompute the output
  //memcpy(newPixels, pixels, size*3);
  ComputeOutput(newPixels, tol1, tol2, useWhite, useBackground);

  // Push back to windows
  if(!SetDIBits(hdc, bitmap, 0, bi.bmiHeader.biHeight, newPixels, &bi, DIB_RGB_COLORS))
      MessageBox(NULL, "Can't set pixel data!", "Error!", MB_ICONEXCLAMATION | MB_OK);

  delete newPixels;
}

, где структура Pixel выглядит так:

struct Pixel { unsigned char b, g, r; };

Почему моя функция обновления не работает.Я всегда получаю MessageBox для "Не могу установить данные пикселей!"Я использовал код, похожий на этот, когда я загружал исходное растровое изображение из файла, затем редактировал данные, но теперь, когда я создаю его вручную, он не работает.

Ответы [ 2 ]

0 голосов
/ 01 января 2011

Пожалуйста, создайте ваше растровое изображение с помощью CreateDIBSection .

Это создает HBITMAP для растрового изображения и возвращает указатель на буфер, доступный для пользовательского режима.В указанном вами формате.

0 голосов
/ 01 января 2011

Для записи в растровое изображение необходимо выбрать его в DeviceContext:

hdcMemDC = CreateCompatibleDC(hdc); 
... // adjust hdcMem to right sizes (see MSDN : Capturing an Image)
SelectObject(hdcMemDC,bitmap);
... // your Bitmap drawing
BitBlt( hdcMemDC, ... ) // to copy to hdc.

ReleaseDC(hWnd, hdcMemDC);

Также для CreateDIBitmap ( GetDC (hwnd) , ...) требуется ReleaseDC (hWnd, ???);

Вы должны присвоить GetDC (...) переменной, чтобы ее можно было освободить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...