赞
踩
功能实现:
代码已开源到github上
使用的是libjpeg库,关于如何在QT中配置libjpeg库的环境,请看我这篇博客
char* input_filename = "C:/Users/10858/Desktop/1.jpg";
char* output_filename_R = "C:/Users/10858/Desktop/output_R.txt";
char* output_filename_G = "C:/Users/10858/Desktop/output_G.txt";
char* output_filename_B = "C:/Users/10858/Desktop/output_B.txt";
FILE* infile = fopen(input_filename, "rb");
if (!infile) {
printf("无法打开文件: %s\n", input_filename);
return 1;
}
fseek(infile, 0, SEEK_END); //文件指针定位到文件结尾位置
size_t size = ftell(infile); //读取文件大小
fseek(infile, 0, SEEK_SET); //文件指针回到文件开始位置
unsigned char* jpegData = new unsigned char[size]; //在堆上分配一个内存块
fread(jpegData, size, 1, infile); //数据读取到刚才分配的内存块中
struct jpeg_decompress_struct cinfo;
jpeg_create_decompress(&cinfo); //创建解压缩对象
jpeg_mem_src(&cinfo, jpegData, size); //设置JPEG解压缩的源数据
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
int ret = jpeg_read_header(&cinfo, TRUE);
if (ret != JPEG_HEADER_OK) {
fprintf(stderr, "Error: jpeg_read_header returned %d\n", ret);
jpeg_destroy_decompress(&cinfo); //释放资源
fclose(infile);
return 1;
}
//开始解压缩JPEG文件 jpeg_start_decompress(&cinfo); //获取图像宽度和高度 int width = cinfo.output_width; int height = cinfo.output_height; //扫描行跨度:计算一行像素所需的字节数 int row_stride = width * cinfo.output_components; //为解压后的图像分配内存 unsigned char* buffer = new unsigned char[width * height * 3]; //读取解压后的图像数据 unsigned char* row_pointer; int row = 0; while (cinfo.output_scanline < height) { row_pointer = buffer + (row * width * 3); jpeg_read_scanlines(&cinfo, &row_pointer, 1); row++; } //结束解压缩JPEG文件 jpeg_finish_decompress(&cinfo);
//结束解压缩JPEG文件
jpeg_finish_decompress(&cinfo);
//关闭输入文件
fclose(infile);
ofstream outfile_R(output_filename_R); if (!outfile_R.is_open()) { printf("无法打开文件: %s\n", output_filename_R); return 1; } ofstream outfile_G(output_filename_G); if (!outfile_G.is_open()) { printf("无法打开文件: %s\n", output_filename_G); return 1; } ofstream outfile_B(output_filename_B); if (!outfile_B.is_open()) { printf("无法打开文件: %s\n", output_filename_B); return 1; } //逐个像素地写入数据 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { // 计算当前像素在缓冲区中的位置 int pos = (i * width + j) * 3; // 将RGB三个分量的值写入txt文件中 outfile_R << static_cast<int>(buffer[pos]) << endl; outfile_G << static_cast<int>(buffer[pos + 1]) << endl; outfile_B << static_cast<int>(buffer[pos + 2]) << endl; } }
outfile_R.close();
outfile_G.close();
outfile_B.close();
//释放内存
delete[] buffer;
//清除JPEG解压缩对象
jpeg_destroy_decompress(&cinfo);
输出结果:
测试图片:
为了验证R、G、B的数据是否正确,需要用这些数据恢复出原始图片
with open('C:/Users/10858/Desktop/output_R.txt') as f:
r_data = [int(x) for x in f.read().split()]
with open('C:/Users/10858/Desktop/output_G.txt') as f:
g_data = [int(x) for x in f.read().split()]
with open('C:/Users/10858/Desktop/output_B.txt') as f:
b_data = [int(x) for x in f.read().split()]
# 创建空白的图片
img = Image.new('RGB', (width, height))
# 填充图片
for y in range(height):
for x in range(width):
r = r_data[y * width + x]
g = g_data[y * width + x]
b = b_data[y * width + x]
img.putpixel((x, y), (r, g, b))
恢复结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。