Re: Сохранение bitmap c bitcount = 8
От: CEMb  
Дата: 17.05.11 15:16
Оценка: -2
Не глядя программу, предположение: при bitcount = 4, 8, bih.biCompression должно быть BI_RLE или как-то так... RLE-сжатие
Re: Сохранение bitmap c bitcount = 8
От: MBo  
Дата: 17.05.11 15:44
Оценка: +1
Здравствуйте, Misha30, Вы писали:

M>Добрый вечер. Обращаюсь к Вам за помощью ибо начинаю медленно сходить с ума. Пытаюсь сохранить раннее полученный HBITMAP в файл. Размер картинки 160*160. При глубине цвета 16 и 32 бита на пиксел работает на ура (выделяю естественно не 160*160 а 160*160*2 и 160*160*4 соответственно). А вот при 8bpp выдает ошибку "stack around variable 'a' was corrupted". Где вообще появляется мифическая переменная 'а' я так и не понял. Надеюсь на Вашу помощь.


У 8-битного битмапа после Infoheader-а идет палитра.
На запись в файл её отсутствие не влияет — ну будет пока некорректный битмап. Так что надо проверять то, что делается до записи — GetDiBits ?
Re: Сохранение bitmap c bitcount = 8
От: icWasya  
Дата: 18.05.11 13:29
Оценка: +1
Здравствуйте, Misha30, Вы писали:

M>Добрый вечер. Обращаюсь к Вам за помощью ибо начинаю медленно сходить с ума. Пытаюсь сохранить раннее полученный HBITMAP в файл. Размер картинки 160*160. При глубине цвета 16 и 32 бита на пиксел работает на ура (выделяю естественно не 160*160 а 160*160*2 и 160*160*4 соответственно). А вот при 8bpp выдает ошибку "stack around variable 'a' was corrupted". Где вообще появляется мифическая переменная 'а' я так и не понял. Надеюсь на Вашу помощь.


M> BITMAPFILEHEADER bfh;

M> BITMAPINFOHEADER bih;
M> BITMAPINFO bi;
M> DWORD dwWB = 0;
M> HANDLE hFile = NULL;

M> unsigned char pdwBits[160 * 160];


M> memset (&bfh, 0, sizeof (BITMAPFILEHEADER));

M> memset (&bih, 0, sizeof (BITMAPINFOHEADER));
M> memset (&bi, 0, sizeof (BITMAPINFO));

M> bih.biSize = sizeof(bih);

M> bih.biBitCount = 8;
M> bih.biCompression = BI_RGB;
M> bih.biHeight = 160;
M> bih.biWidth = 160;
M> bih.biPlanes = 1;
M> bih.biSizeImage = 160 * 160;
M> bih.biClrUsed = 0;

M> bfh.bfType = 0x4D42;

M> bfh.bfOffBits =sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER);
M> bfh.bfSize = bfh.bfOffBits + 160 * 160;


M> bi.bmiHeader = bih;


M> GetDIBits (cwinDC, bmpMem, 0, 160, pdwBits, &bi, DIB_RGB_COLORS);



M> .....

M> break;


Похоже не существует варианта DIB_RGB_COLORS для biBitCount = 8;
Нужно указывать DIB_PAL_COLORS и задать палитру, в которой будет получено изображение.
Сохранение bitmap c bitcount = 8
От: Misha30  
Дата: 17.05.11 14:43
Оценка:
Добрый вечер. Обращаюсь к Вам за помощью ибо начинаю медленно сходить с ума. Пытаюсь сохранить раннее полученный HBITMAP в файл. Размер картинки 160*160. При глубине цвета 16 и 32 бита на пиксел работает на ура (выделяю естественно не 160*160 а 160*160*2 и 160*160*4 соответственно). А вот при 8bpp выдает ошибку "stack around variable 'a' was corrupted". Где вообще появляется мифическая переменная 'а' я так и не понял. Надеюсь на Вашу помощь.

BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
BITMAPINFO bi;
DWORD dwWB = 0;
HANDLE hFile = NULL;

unsigned char pdwBits[160 * 160];

memset (&bfh, 0, sizeof (BITMAPFILEHEADER));
memset (&bih, 0, sizeof (BITMAPINFOHEADER));
memset (&bi, 0, sizeof (BITMAPINFO));

bih.biSize = sizeof(bih);
bih.biBitCount = 8;
bih.biCompression = BI_RGB;
bih.biHeight = 160;
bih.biWidth = 160;
bih.biPlanes = 1;
bih.biSizeImage = 160 * 160;
bih.biClrUsed = 0;

bfh.bfType = 0x4D42;
bfh.bfOffBits =sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER);
bfh.bfSize = bfh.bfOffBits + 160 * 160;


bi.bmiHeader = bih;

GetDIBits (cwinDC, bmpMem, 0, 160, pdwBits, &bi, DIB_RGB_COLORS);


hFile = CreateFile ("save.bmp", GENERIC_WRITE, 0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
if (hFile == INVALID_HANDLE_VALUE) {
if (pdwBits) GlobalFree (pdwBits);
SetWindowText (g_hWnd, "Ошибка при открытии файла");
break;
}
WriteFile (hFile, (void *)&bfh, sizeof (BITMAPFILEHEADER), &dwWB, NULL));
WriteFile (hFile, (void *)&bih, sizeof (BITMAPINFOHEADER), &dwWB, NULL));
WriteFile (hFile, pdwBits, 160 * 160, &dwWB, NULL));

CloseHandle (hFile);
GlobalFree (pdwBits);
break;
bitmapinfoheader bitmapfileheader hbitmap
Re[2]: Сохранение bitmap c bitcount = 8
От: MBo  
Дата: 19.05.11 02:08
Оценка:
Здравствуйте, icWasya, Вы писали:

W>Похоже не существует варианта DIB_RGB_COLORS для biBitCount = 8;

W>Нужно указывать DIB_PAL_COLORS и задать палитру, в которой будет получено изображение.

Это не то — DIB_RGB_COLORS и DIB_PAL_COLORS показывают, как интерпретировать палитру (первое — в ней содержатся непосредственно цвета)

А вот то, что GetDiBits пытается записать много в маленький кусок памяти — вполне вероятная причина вылета.
Re[2]: Сохранение bitmap c bitcount = 8
От: Carc Россия http://www.amlpages.com/home.php
Дата: 19.05.11 08:35
Оценка:
Здравствуйте, icWasya, Вы писали:

W>Здравствуйте, Misha30, Вы писали:


M>>Добрый вечер. Обращаюсь к Вам за помощью ибо начинаю медленно сходить с ума. Пытаюсь сохранить раннее полученный HBITMAP в файл. Размер картинки 160*160. При глубине цвета 16 и 32 бита на пиксел работает на ура (выделяю естественно не 160*160 а 160*160*2 и 160*160*4 соответственно). А вот при 8bpp выдает ошибку "stack around variable 'a' was corrupted". Где вообще появляется мифическая переменная 'а' я так и не понял. Надеюсь на Вашу помощь.


M>> BITMAPFILEHEADER bfh;

M>> BITMAPINFOHEADER bih;
M>> BITMAPINFO bi;
M>> DWORD dwWB = 0;
M>> HANDLE hFile = NULL;

M>> unsigned char pdwBits[160 * 160];


M>> memset (&bfh, 0, sizeof (BITMAPFILEHEADER));

M>> memset (&bih, 0, sizeof (BITMAPINFOHEADER));
M>> memset (&bi, 0, sizeof (BITMAPINFO));

M>> bih.biSize = sizeof(bih);

M>> bih.biBitCount = 8;
M>> bih.biCompression = BI_RGB;
M>> bih.biHeight = 160;
M>> bih.biWidth = 160;
M>> bih.biPlanes = 1;
M>> bih.biSizeImage = 160 * 160;
M>> bih.biClrUsed = 0;

M>> bfh.bfType = 0x4D42;

M>> bfh.bfOffBits =sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER);
M>> bfh.bfSize = bfh.bfOffBits + 160 * 160;


M>> bi.bmiHeader = bih;


M>> GetDIBits (cwinDC, bmpMem, 0, 160, pdwBits, &bi, DIB_RGB_COLORS);



M>> .....

M>> break;


W>Похоже не существует варианта DIB_RGB_COLORS для biBitCount = 8;

W>Нужно указывать DIB_PAL_COLORS и задать палитру, в которой будет получено изображение.
Именно так. По крайней мере когда писал код сохранения из HICON в ico-файл, там приходилось с битмапами именно так сохраняться (а в ico по сути и лежат 2 битмапа + еще инфа).
Aml Pages Home
Re: Сохранение bitmap c bitcount = 8
От: Misha30  
Дата: 23.05.11 11:31
Оценка:
Всем спасибо, отчасти все были правы.
Итак для тех, кто вдруг наткнется на эту ветку с поиском такого же ответа.
Делать GetDIBits надо с флагом DIB_PAL_COLORS, но это лишь требование для получения корректной битмапы. Ошибка же заключалось в том — что если у нас палитра (а она будет для 256-разрядных изображний) объявление BITMAPINFO bmi не выделит нам достаточно места для хранения всей битмапинфы, так как она просто не знает, сколько выделять под палитру и выделит лишь под BITMAPINFOHEADER — известное заранее значение. Выход из этой ситуации — использовать указатель на структуру PBITMAPINFO и выделять —
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD) * (2^(SIZE)));
где SIZE — размер картинки.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.