好的,所以我的代码将在ppm图像的标题中读取,为图像大小分配内存,并成功打印每个像素的空白点(在终端重复的随机数)。我需要知道的是我应该如何读取每个像素的红绿蓝值(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;
}
答案 0 :(得分:0)
PPM files将颜色存储为三倍字节(按顺序为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
,我觉得有点不寻常,因为标题表明你正在使用一个文件。您可以使用fopen
打开文件(不要忘记检查结果),使用fscanf
从中读取,然后使用fclose
将其关闭。
但是,我建议将整个文件读入内存并在那里处理,因为一次读取几个字节的文件很慢。
最后,我们注意到,当您需要width
* height
* bit
时,您只为bytes_per_channel
分配num_channels
* width
个字节* height
,不检查您的malloc
是否失败,而不是rgb
。你应该解决这些问题。