使用 C 读取图像 (PPM)



所以我必须以PPM格式读取此图像,然后将其写入另一个文件。 它可以工作,但是如果图像有注释,它将停止工作。 如果图像如下所示:

P3
3 2
255
255   0   0
0 255   0
0   0 255
255 255   0
255 255 255
0   0   0

它可以工作,但如果图像是这样的:

P3
3 2
255
# "3 2" is the width and height of the image in pixels
# "255" is the maximum value for each color
# The part below is image data: RGB triplets
255   0   0  # red
0 255   0  # green
0   0 255  # blue
255 255   0  # yellow
255 255 255  # white
0   0   0  # black

它停止工作。 我真的不知道为什么,因为我已经编程为忽略评论。 我将在下面保留代码,也许有人可以提供帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct pixel {
unsigned int r,g,b;
} pixel;
typedef struct imagem{
int cols,rows;
char mnumber[2];
int maxcolor;
pixel *matrix;
}imagem;
static imagem read(const char *filename)
{
imagem img;
FILE *f;
f = fopen(filename,"rb");
if(f == NULL) {
scanf("%c %c",&img.mnumber[0],&img.mnumber[1]);
scanf("%d %d",&img.cols,&img.rows);
scanf("%d",&img.maxcolor);
img.matrix = (pixel*) malloc(img.cols*img.rows*sizeof(pixel));
for(int i = 0; i < img.cols*img.rows;i++)
{
scanf("%u %u %u",&img.matrix[i].r,&img.matrix[i].g,&img.matrix[i].b);
}
} else {
int i = 0;
while(i != 2)
{
img.mnumber[i] = getc(f);
//printf("%cn",(char) img.mnumber[i]);
i++;
}

int c = getc(f);
while (c == '#') {
while (getc(f) != 'n') {
getc(f);
}
c = getc(f);
}
ungetc(c, f);

fscanf(f,"%d %d",&img.cols,&img.rows);

fscanf(f,"%d",&img.maxcolor);
img.matrix = (pixel*)malloc(img.cols * img.rows* sizeof(pixel));

for(int i = 0; i < img.cols*img.rows;i++)
{
fscanf(f,"%u %u %u",&img.matrix[i].r,&img.matrix[i].g,&img.matrix[i].b);
}
fclose(f);
return img;
}
return img;
}

我会这样写:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct pixel {
unsigned int r,g,b;
} pixel;
typedef struct imagem{
int cols, rows;
char mnumber[2];
int maxcolor;
pixel *matrix;
} imagem;
static imagem read(const char *filename)
{
imagem img;
FILE *f;
int i;
char buf[BUFSIZ];
if (filename == NULL) {
f = stdin;
} else {
f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr, "Can't open %sn", filename);
exit(1);
}
}
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read datan");
exit(1);
}
for (i = 0; i < 2; i++) {
img.mnumber[i] = buf[i];
}
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read datan");
exit(1);
}
sscanf(buf, "%d %d", &img.cols, &img.rows);
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read datan");
exit(1);
}
sscanf(buf, "%d", &img.maxcolor);
img.matrix = malloc(img.cols * img.rows * sizeof(pixel));
if (img.matrix == NULL) {
fprintf(stderr, "malloc failedn");
exit(1);
}
i = 0;
while (fgets(buf, sizeof buf, f) != NULL) {
if (buf[0] == '#') continue;
else {
sscanf(buf, "%u %u %u", &img.matrix[i].r, &img.matrix[i].g, &img.matrix[i].b);
i++;
}
}    fclose(f);
return img;
}
  • 正如建议的那样,最好使用fgets()sscanf()而不是fscanf(),尤其是当我们需要处理不规则的线条时。
  • 您不必编写特定的代码来读取stdin当 省略文件名。只需将文件指针f分配给stdin即可。
  • 建议将函数名称read()更改为其他名称 因为它与现有的系统调用函数冲突read(2)

相关内容

  • 没有找到相关文章

最新更新