read PPM file and store it in an array; coded with C

前端 未结 2 1642
野的像风
野的像风 2020-12-02 19:46

I need to read a PPM file and store it in an array written in C. Can anybody help me out doing this?

Thanks a lot.

相关标签:
2条回答
  • 2020-12-02 20:11

    Here is the PPM specification.

    The PPM file is built in 9 sections separated by white-spaces.

    • Open the file
    • read until the first white space and check you got P6. Then skip other white-spaces.
    • read until the next white space, convert your buffer to an integer width. Then skip other white-spaces
    • read until the next white space, convert your buffer to an integer height. Then skip other white-spaces
    • Allocate a 2D array of integers in the size of height*width
    • read the max-val
    • read line by line and fill the array
    0 讨论(0)
  • 2020-12-02 20:26

    The following code shows how to read, change the pixel colour and write an image in PPM format. I hope it helps.

    #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();
    }
    
    0 讨论(0)
提交回复
热议问题