用C读取图像(PPM)
所以我必须以PPM格式读取此图像,然后将其写入另一个文件。 但是,如果图像有注释,它将停止工作。 如果图像是这样的:用C读取图像(PPM),c,image,image-processing,ppm,C,Image,Image Processing,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 maximu
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
它可以工作,但如果图像是这样的:
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("%c\n",(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;
}
#包括
#包括
#包括
#包括
typedef结构像素{
无符号整数r,g,b;
}像素;
类型定义结构映像{
int列,行;
字符编号[2];
int-maxcolor;
像素*矩阵;
}imagem;
静态imagem读取(常量字符*文件名)
{
imagem-img;
文件*f;
f=fopen(文件名,“rb”);
如果(f==NULL){
scanf(“%c%c”、&img.mnumber[0]、&img.mnumber[1]);
scanf(“%d%d”、&img.cols、&img.rows);
scanf(“%d”,&img.maxcolor);
img.matrix=(像素*)malloc(img.cols*img.rows*sizeof(像素));
for(int i=0;i
我会这样写:
#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 %s\n", filename);
exit(1);
}
}
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read data\n");
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 data\n");
exit(1);
}
sscanf(buf, "%d %d", &img.cols, &img.rows);
if (fgets(buf, sizeof buf, f) == NULL) {
fprintf(stderr, "Can't read data\n");
exit(1);
}
sscanf(buf, "%d", &img.maxcolor);
img.matrix = malloc(img.cols * img.rows * sizeof(pixel));
if (img.matrix == NULL) {
fprintf(stderr, "malloc failed\n");
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;
}
#包括
#包括
#包括
#包括
typedef结构像素{
无符号整数r,g,b;
}像素;
类型定义结构映像{
int列,行;
字符编号[2];
int-maxcolor;
像素*矩阵;
}imagem;
静态imagem读取(常量字符*文件名)
{
imagem-img;
文件*f;
int i;
char buf[BUFSIZ];
如果(文件名==NULL){
f=stdin;
}否则{
f=fopen(文件名,“r”);
如果(f==NULL){
fprintf(stderr,“无法打开%s\n”,文件名);
出口(1);
}
}
if(fgets(buf,sizeof buf,f)=NULL){
fprintf(stderr,“无法读取数据”);
出口(1);
}
对于(i=0;i<2;i++){
img.mnumber[i]=buf[i];
}
if(fgets(buf,sizeof buf,f)=NULL){
fprintf(stderr,“无法读取数据”);
出口(1);
}
sscanf(基本单位、%d%d、&img.cols和&img.rows);
if(fgets(buf,sizeof buf,f)=NULL){
fprintf(stderr,“无法读取数据”);
出口(1);
}
sscanf(buf、%d、&img.maxcolor);
img.matrix=malloc(img.cols*img.rows*sizeof(像素));
if(img.matrix==NULL){
fprintf(stderr,“malloc失败\n”);
出口(1);
}
i=0;
while(fgets(buf,sizeof buf,f)!=NULL){
如果(buf[0]='#')继续;
否则{
sscanf(buf,“%u%u%u”,&img.matrix[i].r,&img.matrix[i].g,&img.matrix[i].b);
i++;
}
}fclose(f);
返回img;
}
- 正如所建议的,最好结合使用
和fgets()
而不是sscanf()
尤其是当我们需要处理不规则的线条时fscanf()
- 当
文件名被省略。只需将文件指针
分配给f
stdin
- 建议将函数名
更改为其他名称 因为它与现有的系统调用函数read()
冲突read(2)
fscanf
和malloc
调用的返回值。2使用调试器逐步检查代码,观察其流和变量值,以发现哪里出了问题。您的代码只处理一次注释,并且只处理文件的特定部分。只有当注释从文件的第二行开始时,它才有可能工作。因此,很明显,它对给出的示例不起作用,因为这不是注释的起点。在调试器中运行代码(甚至在循环中添加基本调试打印语句)应该清楚地表明注释循环从未运行。实际上,我认为如果注释从第二行开始,它甚至不会工作。因为代码没有正确处理第一行末尾的换行符。与“#”相比,该换行符始终是字符,因此永远不会匹配。同样,更系统地调试代码,您应该可以轻松地发现这些问题。为了处理注释,我会使用fgets
阅读每一行,然后使用strchr
查找
的位置(如果有),并用nul字符\0
替换
。然后,您需要检查该行是否为空,如果为空,则跳过该行。注意:实际图像的每个“行”都需要是4像素字节的倍数,因此单个像素(3字节)将无法正确显示,因此图像中的每个行都需要一个“虚拟”字节