根据uint8_t

时间:2018-06-29 13:47:49

标签: c++ image file-io

我正在尝试从具有给定宽度和高度的文件中读取.bmp灰度图像,将其转换为std::vector<uint8_t>,对该矢量运行某种过滤功能,然后创建一个新的std::vector中的图片。我被困在最后一部分。

如何从给定的std::vector<uint8_t>,高度和宽度创建.bmp文件?

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 :(得分:1)

.bmp文件不仅存储原始像素数据。它以描述文件中存储的图像的标题开头:宽度,高度,像素大小,颜色类型等。您编写的read_image()函数读取整个文件,包括标题,并运行任何图像处理向量上的算法会破坏您的数据并产生垃圾。

如果您正在学习图像处理,则使用原始图像文件会容易得多。原始图像文件仅包含像素数据,而没有任何元数据。使用原始图像文件时,您有责任了解图像的宽度和高度以及像素编码。

将图像文件转换为原始图像文件,反之亦然,这需要使用外部工具。 ffmpeg是这样的工具。 ffmpeg是一种Linux工具,但是应该容易找到适用于任何操作系统的ffmpeg。

用于从几乎任何格式的文件转换为原始图像文件(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查看所有可用的列表格式)。

如果您有幸在ffmpeg软件包中添加了ffplay可用标签,则可以直接在屏幕上查看原始文件:

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

另外,某些图像处理软件还可以打开原始图像文件:gimp,photoshop,...