У меня есть DIB в памяти (я его получаю извлекая кадр из входящего видеопотока, используя функции видеозахвата). Причём я его сжимаю по выбору одним из кодеков установленных в системе.
Мне нужно делать одно из нижеперечисленного:
1) Вырезать из неё некторый квадрат изображения меньший теукщего. ИЛИ
2) Масштабировать. ИЛИ
3) Или сделав первое или второе сделать её GRAYSCALE.
Я попытался сделать так, как описано ниже но не получилось:
HDC MainDC = GetDC(AfxGetApp()->m_pMainWnd->m_hWnd);
HDC FirstDC = CreateCompatibleDC(MainDC);
// LPBYTE pData; - указывает на начало в памяти DIB'а с BITMAPINFO и массивом данных
// LPBITMAPINFOHEADER pTBIH = (LPBITMAPINFOHEADER)pData;
// Data.X1,Data.X2,Data.Y1,Data.Y2 - желаемый квадрат из DIB
StretchDIBits(FirstDC, 0, 0, Data.X2 - Data.X1, Data.Y2 - Data.Y1,
0, 0, Data.X2 - Data.X1, Data.Y2 - Data.Y1,
pData + pTBIH->biSize + pTBIH->biClrUsed * sizeof(RGBQUAD),
(LPBITMAPINFO)pData, DIB_RGB_COLORS, SRCCOPY);
Я так понимаю эта функция копирует квадрат из памяти в FirstDC
Затем пытаюсь извлечь получившуюся картинку:
pTBIH->biWidth = Data.X2 - Data.X1;
pTBIH->biHeight = Data.Y2 - Data.Y1;
HBITMAP hBitmap = CreateCompatibleBitmap(MainDC, pTBIH->biWidth, pTBIH->biHeight);
GetDIBits( FirstDC, hBitmap, 0, (DWORD)pTBIH->biHeight,
pData + pTBIH->biSize + pTBIH->biClrUsed * sizeof(RGBQUAD),
(LPBITMAPINFO)pData, DIB_RGB_COLORS);
Возвращает код ошибки: Параметр задан неверно. (87)
Скорее всего из-за второй переменной.
Но я пробовал и по-другому.
Создал HBITMAP как возврат CreateBitmap;
Выбрал его SelectObject в первый контекст.
StretchBlt во второй.
И оттуда GetDIBits уже от законной HBITMAP, но опять таже ошибка.
Здравствуйте Antony, Вы писали:
A>У меня есть DIB в памяти (я его получаю извлекая кадр из входящего видеопотока, используя функции видеозахвата). Причём я его сжимаю по выбору одним из кодеков установленных в системе.
A>Мне нужно делать одно из нижеперечисленного:
A> 1) Вырезать из неё некторый квадрат изображения меньший теукщего. ИЛИ
A> 2) Масштабировать. ИЛИ
A> 3) Или сделав первое или второе сделать её GRAYSCALE.
A>Я попытался сделать так, как описано ниже но не получилось:
A>HDC MainDC = GetDC(AfxGetApp()->m_pMainWnd->m_hWnd);
A>HDC FirstDC = CreateCompatibleDC(MainDC);
A>// LPBYTE pData; - указывает на начало в памяти DIB'а с BITMAPINFO и массивом данных
A>// LPBITMAPINFOHEADER pTBIH = (LPBITMAPINFOHEADER)pData;
A>// Data.X1,Data.X2,Data.Y1,Data.Y2 - желаемый квадрат из DIB
Вот здесь, прежде чем что-то рисовать в FirstDC, нужно выбрать в него какую-нибудь bitmap. В твоем случае имеет смысл выбрать DIB section, чтобы автоматически получить доступ к битам картинки.
// заполняем BITMAPINFO на основе оригинальной картинки; изменяются только
// размеры, все остальные атрибуты, включая таблицу цветов, копируются без
// изменений
DWORD cbInfo = pTBIH->biSize + pTBIH->biClrUsed * sizeof(RGBQUAD);
BITMAPINFO * pbmi = (BITMAPINFO *)malloc(cbInfo);
if (pbmi == NULL)
...;
memcpy(pbmi, pTBIH, cbInfo);
pbmi->bmiHeader.biWidth = Data.X2 - Data.X1;
pbmi->bmiHeader.biHeight = Data.Y2 - Data.Y1;
pbmi->bmiHeader.biSizeImage = 0;
PVOID pBits;
HBITMAP hBitmap = CreateDIBSection(MainDC, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0);
if (hBitmap == NULL)
...;
HGDIOBJ hOldBitmap = SelectObejct(FirstDC, hBitmap);
A>StretchDIBits(FirstDC, 0, 0, Data.X2 - Data.X1, Data.Y2 - Data.Y1,
A> 0, 0, Data.X2 - Data.X1, Data.Y2 - Data.Y1,
A> pData + pTBIH->biSize + pTBIH->biClrUsed * sizeof(RGBQUAD),
A> (LPBITMAPINFO)pData, DIB_RGB_COLORS, SRCCOPY);
SelectObject(FirstDC, hOldBitmap);
// теперь можно анализировать вырезанный кусок через указатель pBits
Ага, идея понятна, но тут возникла проблема с нижеприведённой функцией:
AF>PVOID pBits;
AF>HBITMAP hBitmap = CreateDIBSection(MainDC, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0);
AF>if (hBitmap == NULL)
AF> ...;
Как раз дело в том, что она возвращает NULL.
С ошибкой: Неправильно задан параметр.
Возможно нельзя эту функцию использовать для сжатой BMP.
Здравствуйте Аноним, Вы писали:
А>Ага, идея понятна, но тут возникла проблема с нижеприведённой функцией:
AF>>PVOID pBits;
AF>>HBITMAP hBitmap = CreateDIBSection(MainDC, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0);
AF>>if (hBitmap == NULL)
AF>> ...;
А>Как раз дело в том, что она возвращает NULL.
А>С ошибкой: Неправильно задан параметр.
А>Возможно нельзя эту функцию использовать для сжатой BMP.
Нельзя. Тогда надо переопределить параметр сжатия в структуре BITMAPINFO, передаваемой на вход этой функции:
pbmi->bmiHeader.biWidth = Data.X2 - Data.X1;
pbmi->bmiHeader.biHeight = Data.Y2 - Data.Y1;
pbmi->bmiCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 0;
Если в итоге надо получить опять же сжатое изображение, то нужно будет вызвать GetDIBits, она умеет генерировать RLE.