ページ 11

アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月06日(月) 16:24
by fuyo
アスキー形式とバイナリー形式の二つのグレースケール画像を識別して読み込み、そのファイルの内容を出力するプログラムを作っているのですが、なかなかうまくいきません。どこがいけないでしょうか。お願いします。

コード:

#include<stdio.h>
#define MAX_IMAGE_SIZE 512
#define NUM 300

int main(int argc, char *argv[])
{
  FILE *fp;
  unsigned char idat[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
  char d[2];
  int i,j;
  int a = 0;
  if(argc!=2){
    printf("Usage: %s [input]\n", argv[0]);
    return 1;
  }

 if((fp=fopen(argv[1], "r"))==NULL){
    printf("input file open error\n");
    return 1;
  }

for(i=0;i<2;i++){
  fscanf(fp,"%d", &d[i]);
    }
 printf("image size: %s\n",d[1]);
   fclose(fp);


 if(d[0]==P2){
   fp=fopen(argv[1], "r");
   fseek(fp,4,SEEK_SET);
   for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
     fscanf(fp,"%d",&idat[i]);
    }
  fclose(fp);
 }else if(d[0]==P5){
   fp=fopen(argv[1], "rb");
   fseek(fp,4,SEEK_SET);
   for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
    fread(&idat[i], sizeof(unsigned char),1,fp);
    }
   fclose(fp);
 }else{
   return 1;
 }

 for(i=0;i<5;i++){
   for(j=0;j<5;j++){
     printf("(%d,%d) gray = %d\n", j,i,idat[a]);
     a++;
   }
 }
  return 0;
}

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月06日(月) 16:52
by bitter_fox
fuyo さんが書きました:アスキー形式とバイナリー形式の二つのグレースケール画像を識別して読み込み、そのファイルの内容を出力するプログラムを作っているのですが、なかなかうまくいきません。どこがいけないでしょうか。
具体的にどこがどううまくいかないのですか?

それからインデントは正しくしっかりつけましょう。

コード:


#include<stdio.h>
#define MAX_IMAGE_SIZE 512
#define NUM 300

int main(int argc, char *argv[])
{
	FILE *fp;
	unsigned char idat[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
	char d[2];
	int i,j;
	int a = 0;
	if(argc!=2){
		printf("Usage: %s [input]\n", argv[0]);
		return 1;
	}

	if((fp=fopen(argv[1], "r"))==NULL){
		printf("input file open error\n");
		return 1;
	}

	for(i=0;i<2;i++){
		fscanf(fp,"%d", &d[i]);
	}
	printf("image size: %s\n",d[1]);
	fclose(fp);


	if(d[0]==P2){
		fp=fopen(argv[1], "r");
		fseek(fp,4,SEEK_SET);
		for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
			fscanf(fp,"%d",&idat[i]);
		}
		fclose(fp);
	}else if(d[0]==P5){
		fp=fopen(argv[1], "rb");
		fseek(fp,4,SEEK_SET);
		for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
			fread(&idat[i], sizeof(unsigned char),1,fp);
		}
		fclose(fp);
	}else{
		return 1;
	}

	for(i=0;i<5;i++){
		for(j=0;j<5;j++){
			printf("(%d,%d) gray = %d\n", j,i,idat[a]);
			a++;
		}
	}
	return 0;
}

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月06日(月) 17:00
by softya(ソフト屋)
なぞの事が多いので読み込むファイルの仕様(テキストとバイナリ)と起動パラメータの仕様を明らかにして下さい。
あと「なかなかうまくいきません」だそうですが、同ダメなのか説明してみてください。

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月06日(月) 22:43
by fuyo
失礼しました。strはchar型にしたのですが、printf("image size: %s x %s\n",d[4], d[6]);のところと if(d[1]==2) else if(d[1]==5)のところがうまく読み取れていないのだと思います。
printf("image size: %s x %s\n",d[4], d[6]);では"4x4"を表示させたくて、if(d[1]==2) else if(d[1]==5)のところではP2かP5かを判別したいです。
さっきとコードを少しかえました。

コード:

#include<stdio.h>
#define MAX_IMAGE_SIZE 512
#define NUM 300

int main(int argc, char *argue[])
{
   FILE *fp;
   unsigned char idat[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
   char d[3];
   int i, j;
   int a = 0;
   if(argc!=2){
      printf("Usage: %s [input]\n", argv[0]);
          return 1;
     }

     if((fp=fopen(argv[1], "r"))==NULL){
          printf("input file open error\n");
          return 1;
     }

     for(i=0;i<3;i++){
          fscans(fp,"%s", &d[i]);
     }
     printf("image size: %s x %s\n",d[1], d[2]);
     fclose(fp);

     if(d[1]==2){
           fp=fopen(argv[1], "r");
           fseek(fp,4,SEEK_SET);
           for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
                fscanf(fp,"%s",&idat[i]);
     }
     fclose(fp);
     }else if(d[1]==5){
   	   fp=fopen(argv[1], "rb");
   	   fseek(fp,4,SEEK_SET);
          for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
    	        fread(&idat[i], sizeof(unsigned char),1,fp);
     }
    fclose(fp);
    }else{
          return 1;
    }

    for(i=0;i<5;i++){
   	for(j=0;j<5;j++){
     		printf("(%d, %d) gray = %s\n", j, i, idat[a]);
    	 	a++;
        }
    }
    return 0;
}


アスキー型
P2
4 4
255
0 0 255 255 0 0 255 255 255 255 0 0 255 255 0 0

バイナリ型
P5
4 4
255
0 0 255 255 0 0 255 255 255 255 0 0 255 255 0 0

お願いします。

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月06日(月) 23:44
by softya(ソフト屋)
調べて見ましたが、これPGMのファイルフォーマットですね?
GIMP2で作って見ましたが、書かれているフォーマットと違うようです。
これが正解なのか、ご自身の書いたた物が正解なのか判断をお願いします。ただ、P2とP5が同じ形式なのは変だと思います。
気になるのは2行目のコメントの有無とP5の実際のフォーマットです。

[追記] それと指摘されていますがインデントが出鱈目です。インデントが何か分からないら聞いて下さい。

[P2] アスキー形式

コード:

P2
# CREATOR: GIMP PNM Filter Version 1.1
4 4
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
[P5] バイナリ形式 16進数ダンプ

コード:

 ADDRESS   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   0123456789ABCDEF 
------------------------------------------------------------------------------
 00000000  50 35 0A 23 20 43 52 45 41 54 4F 52 3A 20 47 49   P5.# CREATOR: GI 
 00000010  4D 50 20 50 4E 4D 20 46 69 6C 74 65 72 20 56 65   MP PNM Filter Ve 
 00000020  72 73 69 6F 6E 20 31 2E 31 0A 34 20 34 0A 32 35   rsion 1.1.4 4.25 
 00000030  35 0A FF FF FF FF FF FF FF FF FF FF FF FF FF FF   5............... 
 00000040  FF FF  

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月07日(火) 00:14
by fuyo
ファイルの形式はPPM形式でした。
実際アスキー型のファイルをcat コマンドで表示すると

$ cat checker4x4_ascii.pgm
P2
4 4
255
0 0 255 255 0 0 255 255 255 255 0 0 255 255 0 0

となり実行すると

$ ./6-1a checker4x4_ascii.pgm
image size: 4x4
(0,0) gray = 0
(1,0) gray = 0
(2,0) gray = 255
(3,0) gray = 255
(0,1) gray = 0
(1,1) gray = 0
(2,1) gray = 255
(3,1) gray = 255
(0,2) gray = 255
(1,2) gray = 255
(2,2) gray = 0
(3,2) gray = 0
(0,3) gray = 255
(1,3) gray = 255
(2,3) gray = 0
(3,3) gray = 0

となればいいのですが、4x4となるはずのところが80x52と分け分からない数字がでてきて、その後が表示されません。

バイナリ型だと
$ ./6-1a checker4x4_binary.pgm
image size: 4x4
(0,0) gray = 0
(1,0) gray = 0
(2,0) gray = 255
(3,0) gray = 255
(0,1) gray = 0
(1,1) gray = 0
(2,1) gray = 255
(3,1) gray = 255
(0,2) gray = 255
(1,2) gray = 255
(2,2) gray = 0
(3,2) gray = 0
(0,3) gray = 255
(1,3) gray = 255
(2,3) gray = 0
(3,3) gray = 0

となるのが正しいです。

分かりにくくてすみません。

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

Posted: 2012年2月07日(火) 11:12
by softya(ソフト屋)
PPMと言うのはP3とP6形式しか無くフルカラー用みたいです。グレイスケールですよね?情報は正確にお願いします。
cat checker4x4_ascii.pgm と名前はpgmですよね?

catで表示されている形式を信用すると、コメントは意識しなくて良いということでよいでしょうか?
規格的にはコメントを考慮する必要があるみたいですが。

まず、プログラムの問題ですが今のプログラムはコンパイルが通りませんので、コンパイルが通るようにしてインデントを直したプログラムを投稿してもらえませんか?
あとコメントもしてみてください。理解度が分かります。

それと文字コードと数値データを混同しているフシが見受けられます。
if( d[1] == 2 )
とかは数字では無く文字のチエックですので
if( d[1] == '2' )
が正しいです。