
http://www1.axfc.net/uploader/Sc/so/74915.c
このppmからpgmにグレースケール化するプログラムをppmからppmのグレースケール化のプログラムに書き換えたのですができた画像を開こうとすると途中で処理が終わっているとエラーメッセージでてグレースケール化した画像が三枚並んでいる画像が出ます。修正箇所があれば教えてください。
ちなみに作ったプログラムは上のプログラムからPGMの部分を消してppmに書き換えています。
またグレースケール化の方法は 重み付けした輝度の計算で処理したいと思っています。こちらの修正もお願いします
(0.299 * R + 0.587 * G + 0.114 * B)
No.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;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAで仕様書は書きますか?
-
空elseの有無
-
ソースコード改造 msペイント
-
例外処理があまり使われない理...
-
C言語(gcc), Linux, FTPプログ...
-
ファイルの開き方
-
あるプログラムのコマンドライ...
-
正しい五十音順について
-
65536は2の何乗なのでしょうか?
-
VBAにてメール作成した際、一部...
-
Vba UserFormを前面に出す方法...
-
寿命
-
COBOLでBLOCK CONTAINS句につい...
-
OS入ってる機器のソフト・アプ...
-
変化させるセルが変化しない
-
C++でアボート(Abort)で処理が...
-
自動クエリとはどういうもので...
-
グループを均等に分けるには?...
-
「Outlookが他のプログラムによ...
-
Bluestacks内でダウンロードし...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAで仕様書は書きますか?
-
空elseの有無
-
C言語(gcc), Linux, FTPプログ...
-
メインプログラム、サブプログ...
-
立脚期の識別ができません…
-
パーレー法のプログラムについて
-
プログラミングのコード量に関...
-
BIOSってどんなCPUで処理してる...
-
ノベルゲームを作成中なのですが、
-
VBからシャットダウンさせる方法
-
1~1000,1001~2000の間に素数が...
-
他人が作ったプログラムのメン...
-
例外処理があまり使われない理...
-
C++ソースからUMLの設計書を作...
-
クリップボードを排他的に利用...
-
MFC,C++/CLI,C#の共存
-
テキストの折り返し処理について
-
日曜プログラマならRubyとPytho...
-
SQLデータベースへのアクセスが...
-
変数・オブジェクト名に漢字使用
おすすめ情報