首页 文章

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

提问于
浏览
8

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

非常感谢 .

2 回答

  • 3

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

    #include<stdio.h>
    #include<stdlib.h>
    
    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;i<img->x*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();
    }
    
  • 20

    这是PPM specification .

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

    • 打开文件

    • 读到第一个空格并检查 P6 . 然后跳过其他白色空格 .

    • 读到下一个空格,将缓冲区转换为整数宽度 . 然后跳过其他白色空格

    • 读到下一个空格,将缓冲区转换为整数高度 . 然后跳过其他白色空格

    • 分配高度*宽度大小的二维整数数组

    • 读取max-val

    • 逐行读取并填充数组

相关问题