在 C 中读取 PGM 图像
Reading PGM Images in C
我正在尝试使用以下函数读取 PGM 图像:
typedef struct PGMImage{
int w;
int h;
unsigned char* data;
}GrayImage;
void ReadPGMImage(char* filename,GrayImage* image)
{
int width,height,size,binary,i,j;
FILE *fp = fopen(filename, "r");
if(!fp){
fprintf(stderr,"Unable to open file in 'r' mode");
exit(errno);
}
readPNMHeader(fp, &width, &height,&binary);
size = width * height;
*image = CreateGrayImage(width,height);
if (!(image->data)){
fprintf(stderr,"Memory not allocated");
exit(errno);
}
fread((void *)image->data, sizeof(unsigned char), (size_t) size, fp);
fclose(fp);
return;
}
我试图阅读的图片有这些 headers:
P2
640 480
255
当我打印出某些像素的值(行:400-410,列:300-310)时,所有像素都会打印“205”,而根据 Matlab 的实际值是:
>248 255 255 250 254 254 254 252 252 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>248 247 249 245 251 252 253 252 245 251
>241 240 243 237 240 244 239 242 243 244
>235 238 238 237 239 238 239 238 240 242
>236 233 241 235 236 234 236 239 235 237
>231 239 231 239 234 234 230 233 233 234
类似的代码在我读取 PPM 图像时有效。谁能告诉我哪里出错了?
编辑:
有效的最终代码:
void ReadPGMImage(char * fileName, GrayImage* image) {
FILE * fp = NULL;
char version[100];
int levels = 0;
unsigned int w = 0, h = 0;
unsigned int i = 0;
int pixdat = 0;
if( fileName == NULL ) {
fprintf(stderr,"Bad file name=%s\n", fileName );
return;
}
fp = fopen(fileName,"rb");
if( fp == NULL ) {
fprintf(stderr,"Cannot open file = %s\n", fileName );
return;
}
fscanf(fp,"%s",version);
SkipComments(fp);
fscanf(fp, "%d", &w);
SkipComments(fp);
fscanf(fp, "%d", &h);
SkipComments(fp);
fscanf(fp, "%d", &levels);
CreateGrayImage(image,w,h);
image->w = w;
image->h = h;
for(i=0;i<w*h;i++) {
fscanf(fp, "%d", &pixdat);
image->data[i] = pixdat;
}
fclose(fp);
return;
}
到目前为止的代码似乎没有问题,只有一点点例外。
我认为以下代码行是问题的原因
*image = CreateGrayImage(width,height);
在这里,您将 CreateGrayImage() 返回的指针分配给覆盖结构内容的 *image。
我假设您想将 CreateGrayImage() 返回的指针传递给 CreateGrayImage() 的调用者。在这种情况下,您需要将 ReadPGMImage() 的函数声明更改为以下内容:
void ReadPGMImage(char* filename,GrayImage** image)
那么它应该会如您所愿地工作。
PGM 以十进制表示数据值,因此请使用 fscanf 读取以下值:
int offset=0;
while(! feof(fp) ){
fscanf(fp, "%hu", &value);
image->data[offset++] = value;
}
%hu 给你 unsigned short 值(即 0..65535 值),因为 PGM 值也可以是短裤作为字节。在此基础上,当你为数据分配内存时,一定要使用:
x->data = (unsigned short*)malloc( width * height * sizeof(unsigned short))
我正在尝试使用以下函数读取 PGM 图像:
typedef struct PGMImage{
int w;
int h;
unsigned char* data;
}GrayImage;
void ReadPGMImage(char* filename,GrayImage* image)
{
int width,height,size,binary,i,j;
FILE *fp = fopen(filename, "r");
if(!fp){
fprintf(stderr,"Unable to open file in 'r' mode");
exit(errno);
}
readPNMHeader(fp, &width, &height,&binary);
size = width * height;
*image = CreateGrayImage(width,height);
if (!(image->data)){
fprintf(stderr,"Memory not allocated");
exit(errno);
}
fread((void *)image->data, sizeof(unsigned char), (size_t) size, fp);
fclose(fp);
return;
}
我试图阅读的图片有这些 headers: P2 640 480 255
当我打印出某些像素的值(行:400-410,列:300-310)时,所有像素都会打印“205”,而根据 Matlab 的实际值是:
>248 255 255 250 254 254 254 252 252 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>248 247 249 245 251 252 253 252 245 251
>241 240 243 237 240 244 239 242 243 244
>235 238 238 237 239 238 239 238 240 242
>236 233 241 235 236 234 236 239 235 237
>231 239 231 239 234 234 230 233 233 234
类似的代码在我读取 PPM 图像时有效。谁能告诉我哪里出错了?
编辑: 有效的最终代码:
void ReadPGMImage(char * fileName, GrayImage* image) {
FILE * fp = NULL;
char version[100];
int levels = 0;
unsigned int w = 0, h = 0;
unsigned int i = 0;
int pixdat = 0;
if( fileName == NULL ) {
fprintf(stderr,"Bad file name=%s\n", fileName );
return;
}
fp = fopen(fileName,"rb");
if( fp == NULL ) {
fprintf(stderr,"Cannot open file = %s\n", fileName );
return;
}
fscanf(fp,"%s",version);
SkipComments(fp);
fscanf(fp, "%d", &w);
SkipComments(fp);
fscanf(fp, "%d", &h);
SkipComments(fp);
fscanf(fp, "%d", &levels);
CreateGrayImage(image,w,h);
image->w = w;
image->h = h;
for(i=0;i<w*h;i++) {
fscanf(fp, "%d", &pixdat);
image->data[i] = pixdat;
}
fclose(fp);
return;
}
到目前为止的代码似乎没有问题,只有一点点例外。
我认为以下代码行是问题的原因
*image = CreateGrayImage(width,height);
在这里,您将 CreateGrayImage() 返回的指针分配给覆盖结构内容的 *image。
我假设您想将 CreateGrayImage() 返回的指针传递给 CreateGrayImage() 的调用者。在这种情况下,您需要将 ReadPGMImage() 的函数声明更改为以下内容:
void ReadPGMImage(char* filename,GrayImage** image)
那么它应该会如您所愿地工作。
PGM 以十进制表示数据值,因此请使用 fscanf 读取以下值:
int offset=0;
while(! feof(fp) ){
fscanf(fp, "%hu", &value);
image->data[offset++] = value;
}
%hu 给你 unsigned short 值(即 0..65535 值),因为 PGM 值也可以是短裤作为字节。在此基础上,当你为数据分配内存时,一定要使用:
x->data = (unsigned short*)malloc( width * height * sizeof(unsigned short))