如何将GIMP生成的C-Source image dump逆向转换为原始图像
解决方法
问题根因
你现有的代码存在两个核心错误,直接导致图像失真:
- 输出的PNM格式不匹配:你使用的
P2是ASCII编码的单通道灰度图格式,但你手里的像素是GIMP定义的2字节RGB16(即RGB565)彩色数据,格式完全不兼容。 - 没有做像素格式解码:2字节的RGB565需要拆分出R、G、B三个通道并映射为0~255的标准8位色值,直接输出原始字节当然会出现颜色、尺寸异常。
方案1:无需写代码,直接用GIMP导入
这是最简单的方案,不用处理编码逻辑:
- 将你的C源文件编译为目标文件:
gcc -c example.c -o example.o - 提取只读数据段的原始二进制内容:
objcopy -O binary --only-section=.rodata example.o image.raw - 打开GIMP,选择
文件>打开,选中生成的image.raw,会自动弹出「原始图像加载」配置窗口:- 宽度填你导出时的数值(你的示例中是304),高度填98
- 偏移量填12:跳过结构体开头的3个4字节
guint成员(width、height、bytes_per_pixel) - 图像类型选
RGB565,根据显示效果调整「小端字节序」勾选状态,确认后即可得到原始图像。
方案2:修正C代码转换为通用PPM图像
你可以参考如下修正后的代码逻辑,直接输出可被任意图像查看器打开的PPM格式文件:
#include <stdlib.h> #include <stdio.h> #include <stdint.h> #include "imgs_press.h" // 替换为你自己的头文件名 int main() { FILE *fp = fopen("original_img.ppm", "wb"); if (!fp) { perror("文件打开失败"); exit(1); } // 输出P6格式二进制PPM头:P6 宽 高 最大色值 fprintf(fp, "P6\n%d %d\n255\n", press_high.width, press_high.height); // 逐像素处理RGB565转RGB888 for (int i = 0; i < press_high.width * press_high.height * 2; i += 2) { // 合并两个字节为16位像素值,如果颜色不对可以调换[i]和[i+1]的顺序 uint16_t pixel = (press_high.pixel_data[i] << 8) | press_high.pixel_data[i+1]; // RGB565拆分:高5位R,中6位G,低5位B,映射到0~255 uint8_t r = (pixel >> 11) * 255 / 31; uint8_t g = ((pixel >> 5) & 0x3F) * 255 / 63; uint8_t b = (pixel & 0x1F) * 255 / 31; // 写入PPM文件 fputc(r, fp); fputc(g, fp); fputc(b, fp); } fclose(fp); return 0; }
编译运行后生成的original_img.ppm可直接导入GIMP使用。
内容的提问来源于stack exchange,提问作者navy1978
相关产品推荐
相关产品推荐

