powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / WinGDI. Преобразование цвета 32 <-> 8. Непонятки с палитрой.
1 сообщений из 1, страница 1 из 1
WinGDI. Преобразование цвета 32 <-> 8. Непонятки с палитрой.
    #34281609
Павел. С
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго времени суток!

Никогда не работал до этого с WinGDI.

Задача - рисовать рисунки и сохранять в BMP файлы. Компрессия RLE, формат - 8 бит на байт.
рисунки в дальнейшем передаются по сети, поэтому размер критичен. Никаких 4х байт на точку нельзя допустить. рисунки не сложные, в основном из закрашенных прямоугольных областей, поэтому RLE дает хороший результат сжатия.

Как делаю:
Сначала
hDC = CreateCompatibleDC()
hBMP = CreateCompatibleBitmap(hDC, w, h)
SelectObject(hDC, hBMP)

потом рисую что надо

Далее описываю BITMAPINFOHEADER:

bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biWidth=w;
bih.biHeight=h;
bih.biPlanes=1;
bih.biBitCount=8;
bih.biCompression=BI_RLE8;
bih.biSizeImage=0;
bih.biXPelsPerMeter=0;
bih.biYPelsPerMeter=0;
bih.biClrUsed=0;
bih.biClrImportant=0;

В нем явно указываю, что хочу по 8 бит на точку.

Затем получаю BITMAPINFO : GetDIBits(hDC, hBmp, 0, 0, NULL, &bi, DIB_RGB_COLORS);
Теперь предполагаю, что в bi.bmiColors лежит палитра, размером 256, тип RGBQUAD
Потом считываю нужные биты картинки : GetDIBits(hDC, hBmp, 0, bi.bmiHeader.biHeight, bmpData, &bi, DIB_RGB_COLORS);

Заполняю BITMAPFILEHEADER.
И пишу всё в файл:
>>BITMAPFILEHEADER>>bi.bmiHeader>>bi.bmiColors>>bmpData

Файл получается нормального формата, читается чем угодно.
Но!!! на месте палитры, лежат какие-то непонятные данные, не похоже на цвета.
И что бы я не рисовал, рисуется цветом 255! (если выключить компрессию, то видно, весь рисунок состоит из 0x00 и 0xFF). А в таблице на этих местах просто непонятные данные! отсюда рисунок состоит совсем не из тех цветов, которые я хотел использовать...

Куда копать??
Как вообще можно преобразовать формат 32 бита на точку в 8 бит на точку? понятно, что потери будут. Но как искать подхлдящие цвета?
Вообще на рисунки всего не больше 10ти разных цветов используется.

Ниже привел код всего этого безобразия:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
	int h= 100 ;
	int w= 200 ;
	BITMAPFILEHEADER hdr;
	BITMAPINFOHEADER bih;     // bitmap info-header 
	BITMAPINFO	bi;

	//BITMAPINFOHEADER
	bih.biSize=sizeof(BITMAPINFOHEADER);
	bih.biWidth=w;
	bih.biHeight=h;
	bih.biPlanes= 1 ;
	bih.biBitCount= 8 ;
	//bih.biCompression=BI_RLE8;
	bih.biCompression= 0 ;
	bih.biSizeImage= 0 ;
	bih.biXPelsPerMeter= 0 ;
	bih.biYPelsPerMeter= 0 ;
	bih.biClrUsed= 0 ;
	bih.biClrImportant= 0 ;

	//BITMAPINFO 
	bi.bmiHeader=bih;
	
	//Create  Dc    
	HDC hDC = CreateCompatibleDC(NULL);
	HBITMAP hBmp = CreateCompatibleBitmap(hDC, w, h);
	

	//BMP
	SelectObject(hDC, hBmp);


	//BRUSH
	hBRUSH = CreateSolidBrush(RGB(0x00,0x70,0x70));
	SelectObject(hDC, hBRUSH);

	//Rectangle
	Rectangle(hDC,  40 , 40 , 80 , 80 );

	//Text
	TextOut(hDC,  20 ,  20 , "test", 4 );
	GetDIBits(hDC, hBmp,  0 ,  0 , NULL, &bi, DIB_RGB_COLORS);

	BYTE * bmpData=(BYTE *)malloc(bi.bmiHeader.biSizeImage);

	GetDIBits(hDC, hBmp,  0 , bi.bmiHeader.biHeight, bmpData, &bi, DIB_RGB_COLORS);

	HANDLE hf = CreateFile("c:\\img.bmp", GENERIC_READ | GENERIC_WRITE, (DWORD)  0 , NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); 
	DWORD dwTmp;

	//BITMAPFILEHEADER
	hdr.bfSize=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*( 1  << bi.bmiHeader.biBitCount) + bi.bmiHeader.biSizeImage;
	hdr.bfType=0x4D42;
	hdr.bfReserved1= 0 ;
	hdr.bfReserved2= 0 ;
	hdr.bfOffBits=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*( 1  << bi.bmiHeader.biBitCount);

    WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL);
    WriteFile(hf, (LPVOID) &bi.bmiHeader, sizeof(BITMAPINFOHEADER), (LPDWORD) &dwTmp, NULL);
	WriteFile(hf, (LPVOID) bi.bmiColors, sizeof(RGBQUAD) * ( 1  << bi.bmiHeader.biBitCount),   (LPDWORD) &dwTmp, NULL);
	
    WriteFile(hf, (LPSTR) bmpData, bi.bmiHeader.biSizeImage, (LPDWORD) &dwTmp,NULL);

    // Close the .BMP file. 
     CloseHandle(hf);
	
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / WinGDI. Преобразование цвета 32 <-> 8. Непонятки с палитрой.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]