質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1389閲覧

bmpファイルのrbg値を書き換えるプログラム

torimoti

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/12/17 19:20

編集2020/12/17 22:42

in.bmpを読み込んでrbg値を書き換え、out.bmpで出力するプログラムです。
in.bmpのrbg値を(blue, green, red)、out.bmpのrbg値を(blue#, green#, red#)とし、
blue# = blue
green# = blue + (red - green)
red# = green# + (green - blue)
を満たすようにrgb値を書き換えたいのですが上手くできません。
どこがおかしいのかご教示ください。

c

1 2#define HEIGHT 400 3#define WIDTH 400 4 5#include <stdio.h> 6int main() 7{ 8 FILE *fr, *fw; 9 int i, j, k; 10 11 unsigned char img[3]; 12 unsigned char header[54]; 13 int br1, br2, br3; 14 unsigned char out1, out2, out3; 15 16 fr = fopen("in.bmp", "rb"); 17 fw = fopen("out.bmp", "wb"); 18 19 if( fr == NULL || fw == NULL ){ 20 printf("Cannot open file\n"); 21 return 1; 22 } 23 24 fread(header, sizeof(unsigned char), 54, fr); 25 fwrite(header, sizeof(unsigned char), 54, fw); 26 27 for( i = 0; i < HEIGHT; i++ ) 28 { 29 for( j = 0; j < WIDTH; j++ ) 30 { 31 fread(img, sizeof(unsigned char), 3, fr); 32 33 br1 = (int)img[0]; 34 if(br1 < 0) br1 = 0; 35 if(br1 > 255) br1 = 255; 36 out1 = (unsigned char)br1; 37 38 br2 = (int)img[0] + ((int)img[2] - (int)img[1]); 39 if(br2 < 0) br2 = 0; 40 if(br2 > 255) br2 = 255; 41 out2 = (unsigned char)br2; 42 43 br3 = br2 + ((int)img[1] - (int)img[0]); 44 if(br3 < 0) br3 = 0; 45 if(br3 > 255) br3 = 255; 46 out3 = (unsigned char)br3; 47 48 for( k = 0; k < 3; k++ ) 49 { 50 fwrite(&out1, sizeof(unsigned char), 1, fw); 51 fwrite(&out2, sizeof(unsigned char), 1, fw); 52 fwrite(&out3, sizeof(unsigned char), 1, fw); 53 } 54 } 55 } 56 57 fclose(fr); 58 fclose(fw); 59 60 return 0; 61} 62

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/12/17 22:01

うまくできないとはどうなるんでしょうか。
thkana

2020/12/17 22:25 編集

読み込ませている画像ファイルのフォーマットは、プログラム中で予期しているものに合致していますか。
torimoti

2020/12/17 22:31

>>y_waiwaiさん in.bmpとout.bmpのrgb値を測定すると計算結果と合わないんです。
torimoti

2020/12/17 22:35

>>thkanaさん それに関しては問題ないはずなんですけど、出力結果が予想と違うんですよね…。
y_waiwai

2020/12/17 23:05

rgb値を測定とはどうやって測定したんでしょう また、 このコードで扱ってるBMPファイルは一般のBMPのフォーマットと違うようですが、 ここで扱ってるBMPのデータ構造に関してなにか資料はありますか?
torimoti

2020/12/17 23:17

>>y_waiwaiさん それはまた別のプログラムを用いたのですが、それも貼った方が良いですか? このbmpファイルのデータ構造に関しての資料は無いです。強いて挙げるならば、柴田望洋さんの新明解c言語入門編と実践編です。 あるbmpファイルのrgb値の平均を出してグレーのbmpファイルを出力するプログラムはこの書き方で動いていたので、プログラムの内容に不備があると考えたのですが…。
y_waiwai

2020/12/17 23:19

そりゃBMPのフォーマットガン無視でデータ書き換えてもそりゃ思うようにならんですが。
thkana

2020/12/17 23:49 編集

> 問題ないはず その言葉、質問される方皆さんおっしゃいます。問題ないはずなのに動かない、と。 「こういう方法で確認してこういう結果を得たので問題ない」と言い切るのでない限り、疑うしかありません。だって、結果は全体としては「問題あり」なのですから、大丈夫と断言出来るところ以外は疑ってかかるしかないでしょう。 > 出力結果が予想と違うんですよね…。 となると、期待する結果、与えたデータ、得られた結果(これはプログラムからわかるか...)を示していただかないと、第三者にはあなたが何に不満なのかさえわかりません。 必要な情報を提示して下さい。
torimoti

2020/12/18 01:30

>>y_waiwaiさん rgb値の平均を出すことでグレーのbmpファイルを出力する際には問題なかったのですが、この場合は何故不具合が出るのでしょうか。 単純に書き換えに関しては、フォーマットを無視してはならないだけですか?
y_waiwai

2020/12/18 01:41 編集

どういう不具合なんですか? その不具合の具体例を出してくれないと、あなたは言い張ってるだけ、にしかなりませんよ。
torimoti

2020/12/18 01:44

>>thkanaさん 仰る通りで問題ないはずという根拠は明確に示せない時点で不備がある可能性がありますね。 根拠になるかはわかりませんが、400×400画素サイズのbmpファイルのrgb値平均を出し、グレーのbmpファイルを出力する不具合のないプログラムがあり、それのコードの内容を核の部分は殆ど変えずに組み、400×400画素サイズのbmpファイルのrgb値書き換えプログラムとして用いています。 出力結果はbmpファイルで出てきますのでここに貼ることは出来ないです。ただ、別のプログラムでrgb値を計測すると、in.bmpとout.bmpの対応するrgb値が指定している公式通りに出力されないことしか言えないです。
fana

2020/12/18 02:00 編集

> 指定している公式通りに出力されない ということになる画素が処理結果の中に1つ以上存在するのでしょうから, そのうちのいくつかの画素に関しての{入力画素値,結果画素値,本来あるべき結果値}を例示されてはどうか. あとは,あなたの観測結果をもっと具体的に述べることはできないのか? 単に「公式通りではない」と言うのではなくて. 例えば,「b#とg#については所望の結果なのだが,r#だけが異なっている」とか言われれば,「r#の計算に用いているg#が問題なんじゃねーの?」とか想像が付くかもしれない.
torimoti

2020/12/18 03:40 編集

>>fanaさん 分かりにくくて申し訳ないです。 観測結果についてですが、出力予想値と実際の出力値b#、g#、r#が全て異なる値となるか、一部異なるか、全て一致するかとなっており、法則性が全く見当たりません。 例えば入力値b:g:r=229:228:232の場合、出力値はb#:g#:r#=229:233:232となるはずが、このプログラムではb#:g#:r#=232:236:235となってしまいます。 対して、入力値b:g:r=247:245:245の場合、出力値はb#:g#:r#=247:247:245となり、実際の出力値もb#:g#:r#=247:247:245となっています。
thkana

2020/12/18 03:56 編集

どこかで区切りがずれてるとか... > 出力結果はbmpファイルで出てきますのでここに貼ることは出来ない 入出力ファイルそれぞれ例えば先頭128バイト分をダンプして貼ることは出来ませんか? > 公式通りに出力されないことしか言えないです。 いえ、具体的な値を示すことができるはずです。 本題ではないですが、 green# = blue + (red - green) red# = green# + (green - blue) つまり red# = blue+red-green+green-brue = red ですね。
fana

2020/12/18 03:55

> red# = blue+red-green+green-brue = red コードでは green# は演算結果を8bitの範囲に丸めているので, 式に明記されていませんが,必ずしも red# = red という話ではないのだろう,と想像します.
fana

2020/12/18 03:56

(最大最小の範囲に抑え込むことを「丸める」とは言わないか…? 何と呼ぶだろう?)
thkana

2020/12/18 03:58

あぁ、飽和させちゃうこともあるんですね。了解。
hero1000

2020/12/18 04:30

デバッガで計算するところで止めて、うまくいくケースとうまく行かないケースを試せないんですか?
guest

回答2

0

ベストアンサー

結果を出力している箇所ですが,forで3回繰り返すのが間違いかと見えます.
(入力の3倍出力している)

for( k = 0; k < 3; k++ ) { fwrite(&out1, sizeof(unsigned char), 1, fw); fwrite(&out2, sizeof(unsigned char), 1, fw); fwrite(&out3, sizeof(unsigned char), 1, fw); }

投稿2020/12/18 03:49

fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Bitmapファイルフォーマット

ヘッダ情報の中には、実際の画像データの位置情報が含まれています。
また、1画素の色数も参照して、画素あたりのバイト数も読み出す必要もあります
もひとつ、X方向の1ラインの先頭アドレスは常に4バイトアライメントされるんでそこらへんも考慮に入れましょう。

これらのデータガン無視でBMPデータをいじろうとしてもうまくいきません

投稿2020/12/17 23:25

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問