2015-11-12 4 views
1

С друзьями мы пытаемся написать приложение для работы с файлами BMP, и мы сделаем все как можно проще, потому что мы только начинаем изучать C и C++. Копирование идет хорошо с новыми реальными размерами линий, но теперь я хочу добавить эффект серого и получить еще одну проблему: правая часть изображения перемещена влево - проверьте фотографии. Что вызывает эту проблему?Работа с BMP - загрузка и сохранение

#include <iostream> 
#include <fstream> 
#include <stdio.h> 
#include <unistd.h> 


using namespace std; 

void ReadBMP() 
{ 
    FILE* f = fopen("test2.bmp", "rb"); 
    FILE* w = fopen("zapis.bmp", "wb"); 

    if(f == NULL) 
     throw "Argument Exception"; 

    unsigned char info[54]; 
    fread(info, sizeof(unsigned char), 54, f); 
    fwrite(info, sizeof(unsigned char), 54, w); 

    int width = *(int*)&info[18]; 
    int height = *(int*)&info[22]; 

    cout << endl; 
    cout << "Width: " << width << endl; 
    cout << "Height: " << height << endl; 



    int realwidth = 3*width+(4 - ((3*width)%4))%4; 
    int volume = height * realwidth; 
    unsigned char* data = new unsigned char[volume]; 

    fwrite(info, sizeof(unsigned char), 54, w); 

    fread(data, sizeof(unsigned char), volume, f); 
    unsigned char color = 0; 

    for(int i = 0; i < volume; i+=3) 
    { 
     color = 0; 
     color+=data[i]*0.114; 
     color+=data[i+1]*0.587; 
     color+=data[i+2]*0.299; 
     data[i] = color; 
     data[i+1] = color; 
     data[i+2] = color; 
    } 


    fwrite(data, sizeof(unsigned char), volume, w); 



    fclose(f); 
    fclose(w); 
    delete(data); 
} 

int main() 
{ 
    ReadBMP(); 
    return 0; 
} 

Input image

Output image

+0

Для записи двоичных данных используйте 'write()', оператор '<<' форматирует текст, даже если файл был открыт в двоичном режиме. –

+0

изменено на fwrite, все еще некоторые проблемы – Ratka

+0

Я на самом деле имел в виду 'fromstream :: write()', но хорошо ... –

ответ

0
unsigned char info[54]; 
fread(info, sizeof(unsigned char), 54, f); 
// fwrite(info, sizeof(unsigned char), 54, w); --- comment this line !!!!!!! 

int width = *(int*)&info[18]; 
int height = *(int*)&info[22]; 

Вы пишете заголовок в файл дважды без необходимости.

1

Ваша формула для размера данных изображения неправильно. Сначала вам нужно найти высоту тона, умножив ширину на байты на пиксель (3 для 24-битного изображения), а затем округляя до ближайшего кратного 4. Затем умножьте высоту на высоту;

int byte_width = width * 3; 
int pitch = byte_width + (4 - byte_width % 4) % 4; 
int volume = pitch * height; 
+0

не работал - изображение вывода такое же, как указано выше – Ratka

+2

@Ratka: В BMP-файле, который вы игнорируете, есть много другой информации. Например, могут быть другие данные между заголовком и данными пикселя. Вы должны посмотреть на смещение (4 байта целое, 10 байт от начала), который сообщает вам точное местоположение данных пикселя, начиная с начала файла. –

+0

Я изменил формулу, но получил еще одну проблему. – Ratka

0

Как я вижу в моем собственном коде (что было написано около 20 лет назад), каждая строка изображения дополняется 0 или более пустых байтов для выравнивания начала байта. Кажется, ваш расчет неправильного выравнивания.

Просто скопируйте & пасты здесь:

unsigned short paddingSize; 
unsigned short bitsPerLine = width * bitsPerPixel; 

if(1 == bitsPerPixel || 4 == bitsPerPixel) 
{ 
    if(bitsPerLine % 8) 
    bitsPerLine += 8; 

    paddingSize = (bitsPerLine/8) % 2; 
} 
else if(8 == bitsPerPixel) 
    paddingSize = 0x0003 & ~((bitsPerLine/8) % 4 - 1); 
else 
    paddingSize = (bitsPerLine/8) % 2; 

Реального размер каждой строки calculatedSize + paddingSize где calculatedSize точно размер строки в байтах, т.е. ceil(bitsPerLine/8) или (bitsPerLine + 7)/8 IC C/C++.

Что я могу сказать о коде, это отлаживается, и он работает. Но я не помню, почему все эти чеки здесь.

+0

Я знаю, что каждая строка добавила «0» байт в конце, но я не понимаю, почему она так сложна? – Ratka

+0

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