读取PPM文件并将其存储在数组中; 用C编码

我需要读取一个PPM文件并将其存储在用C编写的数组中。任何人都可以帮我解决这个问题吗?

非常感谢。

以下代码显示如何读取,更改像素颜色以及以PPM格式写入图像。 我希望它有所帮助。

#include #include typedef struct { unsigned char red,green,blue; } PPMPixel; typedef struct { int x, y; PPMPixel *data; } PPMImage; #define CREATOR "RPFELGUEIRAS" #define RGB_COMPONENT_COLOR 255 static PPMImage *readPPM(const char *filename) { char buff[16]; PPMImage *img; FILE *fp; int c, rgb_comp_color; //open PPM file for reading fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Unable to open file '%s'\n", filename); exit(1); } //read image format if (!fgets(buff, sizeof(buff), fp)) { perror(filename); exit(1); } //check the image format if (buff[0] != 'P' || buff[1] != '6') { fprintf(stderr, "Invalid image format (must be 'P6')\n"); exit(1); } //alloc memory form image img = (PPMImage *)malloc(sizeof(PPMImage)); if (!img) { fprintf(stderr, "Unable to allocate memory\n"); exit(1); } //check for comments c = getc(fp); while (c == '#') { while (getc(fp) != '\n') ; c = getc(fp); } ungetc(c, fp); //read image size information if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) { fprintf(stderr, "Invalid image size (error loading '%s')\n", filename); exit(1); } //read rgb component if (fscanf(fp, "%d", &rgb_comp_color) != 1) { fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename); exit(1); } //check rgb component depth if (rgb_comp_color!= RGB_COMPONENT_COLOR) { fprintf(stderr, "'%s' does not have 8-bits components\n", filename); exit(1); } while (fgetc(fp) != '\n') ; //memory allocation for pixel data img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel)); if (!img) { fprintf(stderr, "Unable to allocate memory\n"); exit(1); } //read pixel data from file if (fread(img->data, 3 * img->x, img->y, fp) != img->y) { fprintf(stderr, "Error loading image '%s'\n", filename); exit(1); } fclose(fp); return img; } void writePPM(const char *filename, PPMImage *img) { FILE *fp; //open file for output fp = fopen(filename, "wb"); if (!fp) { fprintf(stderr, "Unable to open file '%s'\n", filename); exit(1); } //write the header file //image format fprintf(fp, "P6\n"); //comments fprintf(fp, "# Created by %s\n",CREATOR); //image size fprintf(fp, "%d %d\n",img->x,img->y); // rgb component depth fprintf(fp, "%d\n",RGB_COMPONENT_COLOR); // pixel data fwrite(img->data, 3 * img->x, img->y, fp); fclose(fp); } void changeColorPPM(PPMImage *img) { int i; if(img){ for(i=0;ix*img->y;i++){ img->data[i].red=RGB_COMPONENT_COLOR-img->data[i].red; img->data[i].green=RGB_COMPONENT_COLOR-img->data[i].green; img->data[i].blue=RGB_COMPONENT_COLOR-img->data[i].blue; } } } int main(){ PPMImage *image; image = readPPM("can_bottom.ppm"); changeColorPPM(image); writePPM("can_bottom2.ppm",image); printf("Press any key..."); getchar(); } 

这是PPM规范 。

PPM文件由9个部分构成,用空格分隔。

  • 打开文件
  • 读到第一个空格并检查你是否有P6 。 然后跳过其他白色空格。
  • 读到下一个空格,将缓冲区转换为整数宽度。 然后跳过其他白色空格
  • 读到下一个空格,将缓冲区转换为整数高度。 然后跳过其他白色空格
  • 分配高度*宽度大小的2D整数数组
  • 阅读max-val
  • 逐行读取并填充数组