プロが教えるわが家の防犯対策術!

http://www1.axfc.net/uploader/Sc/so/74915.c
このppmからpgmにグレースケール化するプログラムをppmからppmのグレースケール化のプログラムに書き換えたのですができた画像を開こうとすると途中で処理が終わっているとエラーメッセージでてグレースケール化した画像が三枚並んでいる画像が出ます。修正箇所があれば教えてください。
ちなみに作ったプログラムは上のプログラムからPGMの部分を消してppmに書き換えています。

またグレースケール化の方法は 重み付けした輝度の計算で処理したいと思っています。こちらの修正もお願いします
(0.299 * R + 0.587 * G + 0.114 * B)

A 回答 (1件)

実際に問題が起きているプログラムを提示していただけないと、


何が問題なのか、こちらには判断できません。

とりあえず、PGM出力をPPM出力するように変更する場合の一般論として、

・メモリは三倍確保していますか? 
PGMは、width*height バイト、PPM は、width*height*3バイトです。

・メモリへの画素データの書き込みは正しくできていますか?
PGMでは、グレースケール値をimage[y*width+x]に1バイトだけ書き込むことになりますが、
PPMでは、RGB値の3バイトをimage[(y*width+x)*3+0]、image[(y*width+x)*3+1]、image[(y*width+x)*3+2]に書き込む必要があります。グレーケールなPPM画像なら同じ数値を3回。

・ファイルへの出力バイト数は間違えていませんか?
メモリ確保に同じ

・出力ヘッダの識別子は「P6」に変えていますか?
PGMは「P5」で、PPMは「P6」です。

> 重み付けした輝度の計算で処理したい
> (0.299 * R + 0.587 * G + 0.114 * B)

元のプログラムでは、「(R+G+B)/3」になってますから、それを上述の式に変えるだけです。
整数演算の「(299*R+587*G+114*B)/1000」にした方がちょっと速いかな。

この回答への補足

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFSIZE 1024
typedef struct tagPPM
{
int width;
int height;
int maxvalue;
unsigned char *image;
} PPM;

PPM *ppm_create(int width, int height)
{
PPM *ppm;
ppm = (PPM *)malloc(sizeof(PPM));
if (ppm != NULL)
{
ppm->width = width;
ppm->height = height;
ppm->maxvalue = 255;
ppm->image = (unsigned char *)malloc(width * height * 3);
if (ppm->image == NULL)
{
free(ppm);
ppm = NULL;
}
}
return ppm;
}

void ppm_destroy(PPM *ppm)
{
free(ppm->image);
free(ppm);
}

PPM *ppm_load(const char *fname)
{
FILE *fin;
char buf[BUFSIZE];
PPM *ppm;
int f = 0;

ppm = (PPM *)malloc(sizeof(PPM));
if (ppm != NULL)
{
fin = fopen(fname, "r");
if (fin != NULL)
{
buf[0] = 0;
fgets(buf, BUFSIZE, fin);
if (strcmp(buf, "P6\n") == 0)
{
do
{
fgets(buf, BUFSIZE, fin);
} while(buf[0] == '#');
sscanf(buf, "%d %d", &ppm->width, &ppm->height);
do
{
fgets(buf, BUFSIZE, fin);
} while(buf[0] == '#');
sscanf(buf, "%d", &ppm->maxvalue);

ppm->image = (unsigned char *) malloc(ppm->width * ppm->height * 3);
if (ppm->image != NULL)
{
fread(ppm->image, 3, ppm->width * ppm->height, fin);
f = 1;
}
}
fclose(fin);
}
if (f)
return ppm;
ppm_destroy(ppm);
}
return NULL;
}

補足日時:2010/11/18 14:09
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!