我正在尝试从具有给定宽度和高度的文件中读取.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?
}
答案 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,...