Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > [C++] Матрица пикселей в BMP


Автор: Sahon 7.1.2012, 22:58
Программа:
Код
#include <iostream> 
#include <fstream> 
#include <cstdio>
#include <windows.h>

using namespace std; 
 
int main(int argc, char *argv[]) 

    setlocale(LC_ALL, "Russian");
    
    if(argc!=2) { //Если более двух аргументов командной строки
        cout << "Используй: next <имя-файла>, будь мужиком!\n"; 
        return 1; 
    } 
 
    fstream in(argv[1], ios::in | ios::out | ios::binary); 
    if(!in) { 
        cout << "Невозможно открыть файл.\n";
    } 
  
    BITMAPFILEHEADER bmpFileHeader; //Создание bmpFileHeader
    BITMAPINFOHEADER bmpInfoHeader; //Создание bmpInfoHeader
    
    in.read( (char*)&bmpFileHeader, sizeof( bmpFileHeader ) ); //Считывание данных 
    in.read( (char*)&bmpInfoHeader, sizeof( bmpInfoHeader ) ); //в структуры
    
    const int Height = bmpInfoHeader.biHeight, //Создание констант
              Width = bmpInfoHeader.biWidth,
              BpP = bmpInfoHeader.biBitCount,
              ImageSize = bmpFileHeader.bfSize;
    
    const int RowSize = BpP / 8 * Width ;
    int padding = ((24 / bmpInfoHeader.biBitCount) * Width) % 4; //Паддинг - ненужное пространсво в массиве пикселей
    char pixels_orig[Height][RowSize]; //Массив пикселей
    
    in.seekg(bmpFileHeader.bfOffBits, ios::beg); //Перескакиваем в начало массива пикселей
    
    for (int i = 0; i < Height; i++) {
        in.read(pixels_orig[i], (RowSize * (BpP / 8))); //Заполнение одного рядка
        in.seekg(padding, ios::cur); //Проскакиваем паддинг
    }
    
    cout << "Данные " << argv[1] << ":\n"
                 << "\tРазмер файла: " << ImageSize << " байтов = " << (double)ImageSize / 1024 << " килобайтов;\n"
                 << "\tШирина изображения: " << Width << " пикселей;\n"
                 << "\tВысота изображения: " << Height << " пикселей;\n"
                 << "\tБитность: " << BpP << " битов на пиксель.\n";

    char temp;
    
    char pixels_crypted[Height][RowSize];
    
    for (int i = 0; i < RowSize; i++)
        for (int j = 0; j < Height; j++)
            pixels_crypted[j][i] = pixels_orig[j][i];
    
    /*for (int i = 0; i < RowSize; i += 2)
        for (int j = 0; j < (Height / 2); j++) {
            temp = pixels_crypted[j][i];
            pixels_crypted[j][i] = pixels_crypted[(Height - 1) - j][i];
            pixels_crypted[(Height - 1) - j][i] = temp;
            
            //if ()
        }*/                                                                   
    
    //Создаем файл out.bmp
    
    fstream out_create("out.bmp"); 
    
    out_create.close();
    
    fstream out("out.bmp", ios::in | ios::out | ios::binary); 
    
    //Начинается запись в файл out.bmp
     
    in.seekg(0, ios::beg);
    
    char ch;
    for (int i = 1; i <= bmpFileHeader.bfOffBits; i++) {
        in.read(&ch, 1);
        out.write(&ch, 1);
    }
    
    in.close();
    
    for (int i = 0; i < Height; i++) {
        out.write(pixels_crypted[i], (RowSize * (BpP / 8))); //Заполнение одного рядка
        for (int i = 1; i <= padding; i++)
            out.write(0, 1); //Заполняем паддинг
    }
    
    out.close();
    
    return 0; 
}


Программа считывает матрицу пикселей из одного *.bmp, перемешивает их[1] и выводит их в out.bmp. Дело в том, что при выводе в файл перемешанного массива pixels_crypted программа аварийно завершает работу. Думаю, что причина в закомментированных строках кода (понятно, что при компиляции код закомментированным не был).

[1] - перемешивание пикселей: в четных (отсчет с 0) столбцах - пиксели имеют обратный порядок:
вместо 1  получаем 5
            2                   4
            3                   3
            4                   2
            5                   1

ВопросГде я накосячил в программе? smile

Автор: bsa 8.1.2012, 10:39
по идее, твой код вообще не должен компилироваться. так как используются массивы с неконстантным размером.
в закомментированном коде проблем нет.
кстати, алгоритм кодирования не будет работать с не восьмибитными картинками. С черно-белыми тоже могут возникнуть проблемы

Автор: Sahon 8.1.2012, 12:09
Цитата(bsa @ 8.1.2012,  10:39)
по идее, твой код вообще не должен компилироваться. так как используются массивы с неконстантным размером.
в закомментированном коде проблем нет.
кстати, алгоритм кодирования не будет работать с не восьмибитными картинками. С черно-белыми тоже могут возникнуть проблемы

А думаю тебе стоит по-внимательнее посмотреть программу и ты увидишь, что константы все-таки имеются. А теперь, пожалуйста, объясни почему с восьмибитными картинками алгоритм не будет работать?   

Автор: xvr 8.1.2012, 20:46
Цитата(bsa @  8.1.2012,  10:39 Найти цитируемый пост)
по идее, твой код вообще не должен компилироваться. так как используются массивы с неконстантным размером.

Будет в С++11 или в g++ (с его расширениями)

Автор: Sahon 8.1.2012, 20:51
Цитата(xvr @ 8.1.2012,  20:46)
Цитата(bsa @  8.1.2012,  10:39 Найти цитируемый пост)
по идее, твой код вообще не должен компилироваться. так как используются массивы с неконстантным размером.

Будет в С++11 или в g++ (с его расширениями)

Я же написал, что константы присутствуют. Или вы не видите const int?  smile 

Автор: xvr 8.1.2012, 21:07
Цитата(Sahon @  8.1.2012,  20:51 Найти цитируемый пост)
Я же написал, что константы присутствуют. Или вы не видите const int?  

Это неправильные константы. Они вычисляются в процессе работы программы. Делать массивы с границами, определяемыми такими константами можно только в С99 (а за ним и в С++11). Ну и GNU по традиции все расширения С99 (да и свои собственные) распространил на С++ (не дожидаясь выхода стандарта)


Автор: bsa 9.1.2012, 12:08
Цитата(Sahon @  8.1.2012,  13:09 Найти цитируемый пост)
А теперь, пожалуйста, объясни почему с восьмибитными картинками алгоритм не будет работать?    

именно с восьмибитными он работать и будет. А вот с 16-ти- и 1-нобитными нет. Потому что там для одного пикселя используется не 1 байт (в первом случае 2, а во втором одна восьмая).
Цитата(Sahon @  8.1.2012,  21:51 Найти цитируемый пост)
Я же написал, что константы присутствуют. Или вы не видите const int?
массивы формируются на этапе компиляции. поэтому когда я говорил о константах, то говорил о константах времени компиляции. А у тебя константы времени выполнения.
В стандарт С++11 введена поддержка подобных массивов. Просто меня сильно удивляет, почему новичок начинает с подобных конструкций...

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