Создание изображения в градациях серого .bmp из вектора uint8_t - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь прочитать .bmp изображение в градациях серого из файла с заданной шириной и высотой, преобразовать его в std::vector<uint8_t>, запустить какую-то функцию фильтра для этого вектора, а затем создать новое изображение из этого std::vector. Я застрял в последней части.

Как мне создать файл .bmp из заданных std::vector<uint8_t>, высоты и ширины?

P.S. Я пытаюсь сделать это без использования внешних библиотек.

Это код, который у меня есть:

class Image {
    int weight;
    int width;
    std::vector<uint8_t> image;
    Image(int weight,int width) : weight(weight),width(width);
    void read_image(char* pic);
    void save_image(const std::vector<uint8_t>& new_image);
    std::vector<uint8_t> filter_image(int ww,int wh,double filter);
};

void Image::read_image(char *pic) {
    std::ifstream file(pic,std::ios_base::in | std::ios_base::binary);
    if(!file.is_open()) return;
    while(file.peek()!=EOF){
        this->image.push_back(static_cast<uint8_t>(file.get()));
    }
}

void Image::save_image(const std::vector<uint8_t> &new_image) {
    //what to do here?
}

1 Ответ

0 голосов
/ 29 июня 2018

Файл .bmp хранит не только необработанные пиксельные данные. Он начинается с заголовка, описывающего изображение, хранящееся в файле: ширина, высота, размер пикселя, тип цвета и т. Д. Написанная вами функция read_image() читает весь файл, включая заголовок, и запускает любой алгоритм обработки изображения в ваш вектор испортит ваши данные и создаст мусор.

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

Преобразование файла изображения в файл необработанного изображения и наоборот предполагает использование внешнего инструмента. ffmpeg - это такой инструмент. ffmpeg - это инструмент linux, но его легко найти, упакованный для любой операционной системы.

Для преобразования из файла практически любого формата в необработанный файл изображения (ffmpeg определяет размер изображения из входного файла). Порядок каждого параметра важен:

ffmpeg -i your_file.jpeg -f rawvideo -c rawvideo -pix_fmt gray output.raw

При конвертации обратно в ваш формат ввода вы должны явно указать ffmpeg размер вашей картинки. Опять важен порядок каждого параметра:

ffmpeg -f rawvideo -c rawvideo -pix_fmt gray -s 1280x720 -i input.raw your_processed_file.jpeg

Адаптируйте ширину и высоту к реальному размеру вашего изображения, иначе ffmpeg изменит размер изображения. Вы также можете поиграть с типом пикселя: gray указывает формат серой шкалы 8 бит на пиксель, но вы можете использовать rgb24 для сохранения информации о цвете (используйте ffmpeg -pix_fmts для просмотра списка всех доступных форматов).

Если вам посчастливилось иметь ffplay в вашем пакете ffmpeg, вы можете просмотреть необработанный файл прямо на экране:

ffplay -f rawvideo -c rawvideo -pix_fmt gray -s 1280x720 input.raw

Кроме того, некоторые программы для обработки изображений могут открывать необработанный файл изображения: gimp, photoshop, ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...