Автор
|
Тема: RGB
|
MrSergei |
опубликован 23-10-2001 01:59 MSK
У меня проблема, написал код для записи RGB интенсивности для каждого пикселя из битмапа в текстовый файл. Так вот он работает только с 24 и 32 битными картинками, а необходимо чтоб работал с 8 и 16 битными, подскажите, пожалуйста, что надо изменить в коде, чтоб работал с 8&16. И в чем собственно проблема. СпасибоВот код: void CMainWnd::SaveAsArray(LPCTSTR filename) { int BytesPerPixel = (lpBitmap->biSizeImage) /(lpBitmap->biHeight * lpBitmap->biWidth); int WidthBytes = lpBitmap->biWidth * BytesPerPixel; int size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * lpBitmap->biClrUsed; BYTE *Bits = (LPBYTE)lpBitmap + size; BYTE * ScanLine; BYTE * Data; BYTE Red, Green, Blue; CStdioFile skadr; CString string; skadr.Open(filename, CFile::modeCreate|CFile::modeWrite); for( int y = lpBitmap->biHeight; y>0; --y ) { ScanLine = Bits + (WidthBytes * (y-1)); Data = ScanLine; for( int x = 0; x<lpBitmap->biWidth - 1; ++x ) { LPRGBQUAD Quad = (LPRGBQUAD) Data; Blue = Quad->rgbBlue; Green = Quad->rgbGreen; Red = Quad->rgbRed;
BYTE color = (Red + Green + Blue)/3; string.Format("\t %d", color); skadr.WriteString(string); Data += BytesPerPixel; } string.Format("\n" ); skadr.WriteString(string); } skadr.Close(); }
|
m_fox
|
опубликован 23-10-2001 08:34 MSK
В таких битмапах цвет пиксела хранится в таблице цветов. А сама bmp'шка хранит номера цветов в этой таблице. И, кстати, не забывай, что в bmp кратность строки = 4 байтам, не зависимо от bmWidth |
Kostik
|
опубликован 23-10-2001 15:19 MSK
Посмотри на Codeguru как люди создают *.bmp тебе поможет. |
MrSergei
|
опубликован 23-10-2001 19:28 MSK
Тогда надо написать, что lpBitmap->biWidth * 4? Значит ли, что структура, к примеру 8-ми битного битмапа идет таким образом (пропуская BITMAPFILEHEADER и BITMAPINFO), красный; data+= байт; зеленый; data+=байт; синий; data+=байт; //пропуск резервного data+=байт; Если так, то откуда брать цвета, ведь структура RGBQUAD уже не поможет? Т.е. какой аналог будет строке: Red = Quad->rgbRed; |
m_fox
|
опубликован 24-10-2001 17:18 MSK
typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; }; Если картинка 16 бит, массив пикселей состоит из последовательности 16-ти битных слов, где RGB представлены по 5 бит. Если картинка 256 цветов, то bmiColors содержит 256 элементов, каждый из которых определяет некоторый RGB цвет ,а массив пикселей состоит из байтовых значений, указывающий интдекс в масиве bmiColors с кратностью 4-м: например, у тебя картинка 5х2 пикселей: 12345 12345 а в bmp записано: 12345000 12345000 , т.е. последовательность дополняется нулями, до кратности 4-м байтам (а не пикселям) |
MrSergei
|
опубликован 24-10-2001 18:17 MSK
Извини, m_fox, что я туплю. Привык в Дельфях и на паскале программировать (если можно назвать настоящим программированием на этих языках), а вот когда серьезными вещами начал заниматься, т.е. перешел на Visual C++ (надо по работе), то сразу понял, что мне еще огого как далеко до понимания всего сущего.Как я понял для 8-ми битного битмапа: вначале я пропускаю всю фигню с заголовками, BYTE *Bits = (LPBYTE)lpBitmap + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * lpBitmap->biClrUsed; значит потом идет массив пикселей каждая строка (визуально представленная на картинке по горизонтали) внутри 8-ми битного битмапа будет BYTE WidthBytes = lpBitmap->biWidth * BytesPerPixel; (или нет?) где BytesPerPixel = lpBitmap->biBitCount / 8; (верно?) а как тогда в цикле отсекать те нули, которые необходимы для кратности, и значения Blue = Quad->rgbBlue; Green = Quad->rgbGreen; Red = Quad->rgbRed; все еще в силе? т.е. для 8-ми битного битмапа можно пользоваться структурой RGBQUAD? если нет, то как вытаскивать значения для цветов, т.е. какой аналог вышенаписанным выражениям Спасибо за помощь! |
m_fox
|
опубликован 25-10-2001 18:56 MSK
Да, пиксели так будут идти.Пусть картинка 256 цветов, тогда байт в строке будет: rx=bmpHdr.biWidth/4; if (bmpHdr.biWidth%4) rx++; rx*=4; rx - это число байт в строке r=bmiColors[n]->rgbRed g=bmiColors[n]->rgbGreen b=bmiColors[n]->rgbBlue
n - это значение ячейки в битовом массиве |
MrSergei
|
опубликован 26-10-2001 01:10 MSK
А для 16 битного битмапа в таком случае будетrx=bmpHdr.biWidth/16; if (bmpHdr.biWidth%16) rx++; rx*=16; Или здесь уже другая кратность? Я сделал способом r=bmiColors[n]->rgbRed g=bmiColors[n]->rgbGreen b=bmiColors[n]->rgbBlue В результате получилось картинка, которая состоит из простого набора цветов, т.е. от 0 до 255, по каждой строке. Используя мой код, мне удается сохранять значения, но только 8 и 16 битные картинки получаются не верными, к примеру у 8-ми битной картинки у одного пикселя должно быть 125 125 125 (R G B) а у меня получается 31 31 31 Почему так, не знаю? У меня просто есть конвертер, написанный на паскале, который переводит текстовый файл, состоящий из массива интенсивностей, в битмап и его отображает, на нем и проверяю. 16 битный битмап, используя мой код, получается размазанным, видно, что он сохранил картинку, но она как-будто в сильном не в фокусе. |
m_fox
|
опубликован 26-10-2001 19:10 MSK
Я же говорил, что с помощью таблицы bmp только 8 и менее бит на пиксел. 16 бит хранятся как rgb (а'ля 24 бит), только на каждую компоненту 5 бит: 16=1+5(red)+5(green)+5(blue) |
MrSergei
|
опубликован 27-10-2001 16:21 MSK
Извини, что опять торможу, но как тогда быть в случае с 16 битным битмапом, если у 8-ми битного кратность 4, то как записать для 16-ти битного? rx=bmpHdr.biWidth/4; if (bmpHdr.biWidth%4) rx++; rx*=4;И как быть с единичкой в начале формулы, как ее пропускать? 16=1+5(red)+5(green)+5(blue) |
m_fox
|
опубликован 27-10-2001 18:41 MSK
не важно какой формат. кратность строки 4м байтам!!! если изображение 16бит, Width=5, то строка: rx=(bmpHdr.biWidth*2)/4; if ((bmpHdr.biWidth*2)%4) rx++; rx*=4; rx - число байт в строке.Windows 95/98: When the biCompression member is BI_BITFIELDS, the system supports only the following 16bpp color masks: A 5-5-5 16-bit image, where the blue mask is 0x001F, the green mask is 0x03E0, and the red mask is 0x7C00; and a 5-6-5 16-bit image, where the blue mask is 0x001F, the green mask is 0x07E0, and the red mask is 0xF800.
|