WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  RGB

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   RGB
MrSergei опубликован 23-10-2001 01:59 MSK   Click Here to See the Profile for MrSergei   Click Here to Email MrSergei  
У меня проблема, написал код для записи 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     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
В таких битмапах цвет пиксела хранится в таблице цветов. А сама bmp'шка хранит номера цветов в этой таблице.
И, кстати, не забывай, что в bmp кратность строки = 4 байтам, не зависимо от bmWidth
Kostik опубликован 23-10-2001 15:19 MSK     Click Here to See the Profile for Kostik  Click Here to Email Kostik     
Посмотри на Codeguru как люди создают *.bmp тебе поможет.
MrSergei опубликован 23-10-2001 19:28 MSK     Click Here to See the Profile for MrSergei  Click Here to Email MrSergei     
Тогда надо написать, что
lpBitmap->biWidth * 4?
Значит ли, что структура, к примеру 8-ми битного битмапа идет таким образом (пропуская BITMAPFILEHEADER и BITMAPINFO),
красный;
data+= байт;
зеленый;
data+=байт;
синий;
data+=байт;
//пропуск резервного
data+=байт;
Если так, то откуда брать цвета,
ведь структура RGBQUAD уже не поможет?
Т.е. какой аналог будет строке:
Red = Quad->rgbRed;
m_fox опубликован 24-10-2001 17:18 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
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     Click Here to See the Profile for MrSergei  Click Here to Email MrSergei     
Извини, 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     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Да, пиксели так будут идти.

Пусть картинка 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     Click Here to See the Profile for MrSergei  Click Here to Email MrSergei     
А для 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     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Я же говорил, что с помощью таблицы bmp только 8 и менее бит на пиксел.
16 бит хранятся как rgb (а'ля 24 бит), только на каждую компоненту 5 бит: 16=1+5(red)+5(green)+5(blue)
MrSergei опубликован 27-10-2001 16:21 MSK     Click Here to See the Profile for MrSergei  Click Here to Email MrSergei     
Извини, что опять торможу, но как тогда быть в случае с 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     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
не важно какой формат. кратность строки 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.

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.