首页 文章

从ppm文件C中的像素获取0-255值

提问于
浏览
0

好的,所以我的代码将在ppm图像的 Headers 中读取,为图像大小分配内存,并将成功打印每个像素的空白点(在终端中重复的随机数) . 我需要知道的是我应该如何读取每个像素的红绿蓝值(3个单独的值,范围从0-255) . 我不知道如何在每个像素内访问这些数据 . 这是我到目前为止的代码:

#include <stdio.h>
#include <stdlib.h>

int subscript(int row,int column,int numberColumns);
int sub(int rd, int gr, int bl);
//table of contents for the subscript
int main(void){
        char header[5];
        scanf("%s",header);
        printf("%s",header);
        printf("\n");
        int width, height, depth;
        scanf("%d %d %d\n", &width, &height, &depth);
        printf("%d %d %d\n", width, height, depth);
        int red = 0;
        int green = 0;
        int blue = 0;
        int sm;
        int r = 0;
        int c = 0;
        //allocate memory for bit to be used throughout main
        unsigned char *bit = malloc(width*height);
        int *rgb = malloc(3*depth);
        //loops to read in table and print it
        while(r < height){
                while(c < width)
                        {
                        int col;
                        scanf("%d",&col);
                        //brings in allocated memory and values
                        bit[subscript(r,c,width)] = col;
                        int clr;
                        rgb[sub(red,green,blue)] = clr; 
                        int color = clr + col;
                        printf(" %d",clr);
                        c=c+1;
                        }
                printf("\n");
                r = r + 1;
                c = 0;
                }


        free(bit);

}
int subscript(int row,int column, int numberColumns)
        {
        return row * numberColumns + column;
        //retuns items for subscript
}

int sub(int rd, int gr, int bl)
        {
        return rd+gr+bl;
}

1 回答

  • 0

    PPM files如果 Headers 中的最大颜色值字段小于256,则将颜色存储为三倍字节(r,g和b各按一个字节),如果为256或更大,则存储两个字节的三倍(因此两个字节)对于r,g和b中的每一个,再次按此顺序) .

    在每通道两个字节的情况下,字节是MSB优先(big-endian) .


    scanf("%c", &byte_var); 会将单个字符(字节)读入 byte_var ,这应该是一个合适的类型 . 然后,您可以相应地处理它 . 如果您使用C99, scanf("%hhu", &byte_var); 将读取无符号字符 - 如果您使用的是C89,则应查找 getchar .

    现在, scanf 返回成功转换的参数或EOF的数量,因此您应该检查错误输入和输入结束的结果 . 例如:

    int n;
    char c;
    
    while ((n = scanf("%c", &c)) != EOF && 1 == n) {
        // do something
    }
    

    使用此示例的示例是:

    // Read width, height, work out how many bytes you need per pixel.
    ...
    
    // Now read some pixels
    // Here I assume one byte per pixel; this would be a good situation
    // to use a function for reading different channel widths
    
    w = 0, h = 0;
    while ((n = scanf("%hhu%hhu%hhu", &r, &g, &b)) != EOF && 3 == n
            && w < width && h < height) {
      // now do something with r, g, b
      // e.g. store them in an appropriate pixels array at pixels[w][h] 
      ...
    
      ++w;
      if (w == width) {
        w = 0, ++h;
      }
    }
    

    我也看到你正在阅读 stdin ,我觉得有点不寻常,因为 Headers 表明你正在使用一个文件 . 您可以使用 fopen 打开文件(不要忘记检查结果),使用 fscanf 从中读取,然后使用 fclose 将其关闭 .

    但是,我建议将整个文件读入内存并在那里进行处理,因为一次读取几个字节的文件很慢 .


    最后,我注意到,当你需要 bytes_per_channel * num_channels * width * height 时,你只为 bit 分配 width * height 字节,而不是检查你的 malloc 是否失败,而不是释放 rgb . 你应该解决这些问题 .

相关问题