Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Работа с изображением


Автор: Mr_Nuke 12.6.2012, 20:05
Всем привет! Пишу прогу, нужно прочитать изображение, а потом его образно записать. 

Код получился таким:
Код

FILE *filePtr, *filePtr2;    
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER bitmapInfoHeader;
    
filePtr = fopen(path,"rb");
filePtr2 = fopen("output.bmp","wb");
    
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);
fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr);

fwrite(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr2);
fwrite(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr2);
    
char *bitmapImage = new char[bitmapInfoHeader.biHeight*bitmapInfoHeader.biWidth*3];
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);

fread(bitmapImage, bitmapInfoHeader.biHeight*bitmapInfoHeader.biWidth*3, 1, filePtr);
fwrite(bitmapImage, bitmapInfoHeader.biHeight*bitmapInfoHeader.biWidth*3, 1, filePtr2);    


Проблема в том, что полученное изображение получается меньше исходного. В редакторе открывается, но не дорисовывается небольшая часть изображения. 

Если в коде, при выделении памяти и чтении, умножать не на 3, а на 4, полученное изображение больше исходного, но в редакторе открывается без искажений. 

А на 3 умножаю т.к. biBitCount = 24 (Every three bytes in the bitmap’s data field represent the relative intensities of blue, green and red for (BGR) every pixel.)

Автор: Mr_Nuke 12.6.2012, 23:59
Проблему нашел! Забыл закрыть поток, откуда пишу!! 
Решено! Закрываем smile

Автор: Mr_Nuke 13.6.2012, 15:53
Рано радовался, это оказалось только верхушкой айсберга!!

Вычитал такую фразу 
Цитата

Размер строки данных в изображении bmp должнен быть кратен четырём (в байтах). Это происходит если используется 1,2,4,8,16,24 бита на канал. Например, у нас есть изображение шириной в 3 пикселя и мы используем 16-битный цвет. Ширина строки: 16*3 = 48 (6 байт). Но длина строки должна быть кратной четырём, поэтому добавляются ещё два байта и длина строки в данном примере будет равна восьми байтам.


Делаем как в примере, есть изображение 2х3 пикселя, 24 бита на канал. Ширина строки получается 24*3 = 72 (9 байт). Добавляем 3 байта для кратности 4, в каждую строку, итого нужно добавить 6 байт. 

Опытным путем установил, что размер полученного изображения все-равно получается меньше, а добавлять надо не 6, а 8 байт, то есть по 4 на строку. 

Почему? И как тогда рассчитать количество добавляемых байт в строке. 
Код

char *bitmapImage = new char[bitmapInfoHeader.biHeight*bitmapInfoHeader.biWidth*3+8];
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
fread(bitmapImage, bitmapInfoHeader.biHeight*bitmapInfoHeader.biWidth*3+8, 1, filePtr);
fwrite(bitmapImage, bitmapInfoHeader.biHeight*bitmapInfoHeader.biWidth*3+8, 1, filePtr2);

Автор: BorisVorontsov 18.6.2012, 13:30
Mr_Nuke, посмотри мой пример работы с растровыми изображениями: http://code.google.com/p/graphicsdemo-open/source/checkout
В функции GetImagePixels разбор заголовка и учет выравнивания строк

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)