🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

2回答

3378閲覧

bmpファイルの指定範囲を塗りつぶすプログラム

sigure666

総合スコア14

C

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

0グッド

0クリップ

投稿2021/01/07 17:54

編集2021/01/07 23:29

bmpファイルを読み込み、コマンドライン引数で指定した範囲のみを黒く塗りつぶすプログラムを分割コンパイルで実装することを想定しています。
ですが、gcc main.c read.c write.c erase.c -o mainでコンパイルし、./main 50 200 250 350で実行した結果、bmpファイルが黒塗りの画像となって出力されてしまいました。

またerase.cのout[i][j][0] = 0、out[i][j][1] = 0、out[i][j][2] = 0の値を全て255に変更し、白色で塗りつぶすプログラムにしてみた所、黒塗りの画像にコマンドライン引数で指定した範囲のみが白色で塗りつぶされた画像が出力されました。

上記の試行から、プログラム内のどこかで一度画像全体を黒で塗りつぶす操作が行われており、そこを修正すれば指定した範囲のみが塗りつぶされ、指定範囲外は元のbmpファイルを維持した状態で出力される、と考えられるのですが、件の問題があるであろう箇所を特定することができませんでした。

どこに不備があるのか教えていただけないでしょうか。

c

1/*main.c*/ 2 3#include <stdio.h> 4#include <stdlib.h> 5#include "imagedata.h" 6 7extern int erase( int x1, int x2, int y1, int y2 ); 8 9unsigned char img[HEIGHT][WIDTH][3]; 10unsigned char out[HEIGHT][WIDTH][3]; 11unsigned char header[54]; 12 13int main(int argc, char** argv) 14{ 15 int x[2]; 16 int y[2]; 17 int i; 18 19 for( i = 0; i < 2; i++) 20 { 21 x[i] = atoi(argv[i+1]); 22 y[i] = atoi(argv[i+3]); 23 if( x[i] > HEIGHT ) x[i] = 400; 24 if( y[i] > WIDTH ) y[i] = 400; 25 } 26 27 read_image("in.bmp"); 28 29 erase((int)x[0], 30 (int)x[1], 31 (int)y[0], 32 (int)y[1]); 33 34 write_image("out.bmp"); 35 36 return 0; 37} 38 39/*imagedata.h*/ 40 41#define HEIGHT 400 42#define WIDTH 400 43 44extern unsigned char img[HEIGHT][WIDTH][3]; 45extern unsigned char out[HEIGHT][WIDTH][3]; 46extern unsigned char header[54]; 47 48extern int read_image(char* filename); 49extern int write_image(char* filename); 50 51/*erase.c*/ 52 53#include <stdio.h> 54#include "imagedata.h" 55 56int erase( int x1, int x2, int y1, int y2 ) 57{ 58 int i, j; 59 60 for( i = y1; i < y2; i++ ) 61 { 62 for( j = x1; j < x2; j++) 63 { 64 out[i][j][0] = 0; 65 out[i][j][1] = 0; 66 out[i][j][2] = 0; 67 } 68 } 69 70 return 0; 71} 72 73/*write.c*/ 74 75#include <stdio.h> 76#include "imagedata.h" 77 78int write_image(char* filename) 79{ 80 FILE *fw; 81 int i, j; 82 83 fw = fopen(filename, "wb"); 84 85 if( fw == NULL ){ 86 printf("Cannot open file\n"); 87 return 1; 88 } 89 90 fwrite(header, sizeof(unsigned char), 54, fw); 91 92 for( i = 0; i < HEIGHT; i++ ){ 93 for( j = 0; j < WIDTH; j++ ){ 94 fwrite(out[i][j], sizeof(unsigned char), 3, fw); 95 } 96 } 97 98 fclose(fw); 99 100 return 0; 101} 102 103/*read.c*/ 104 105#include <stdio.h> 106#include "imagedata.h" 107 108int read_image(char* filename) 109{ 110 FILE *fr; 111 int i, j; 112 113 fr = fopen(filename, "rb"); 114 115 if( fr == NULL ){ 116 printf("Cannot open file\n"); 117 return 1; 118 } 119 120 fread(header, sizeof(unsigned char), 54, fr); 121 122 for( i = 0; i < HEIGHT; i++ ){ 123 for( j = 0; j < WIDTH; j++ ){ 124 fread(img[i][j], sizeof(unsigned char), 3, fr); 125 } 126 } 127 128 fclose(fr); 129 130 return 0; 131}

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

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

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

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

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

episteme

2021/01/07 21:55

read_image("in.bmp"); // erace(...) しない write_image("out.bmp"); ってやったら元の画像がコピーできますか?
sigure666

2021/01/07 23:25

確認してみましたがそもそも元の画像がコピーできてませんでした。 これは読み込みの時点に問題があるということでしょうか?
dodox86

2021/01/08 01:28

Windowsのビットマップファイルは、ビットマップファイルと一口に言っても様々なフォーマットがあります。色数、パレット、一画素あたりのビット幅、透明度、などなど。加えて画像の幅、高さです。質問者さんが扱っているin.bmpファイルのフォーマット、画像の幅、高さと、プログラムで意識しているものが一致しているのが大前提です。それは大丈夫でしょうか。過去の質問でも、フォーマットを意識していない故の問題が何度も投稿されています。
sigure666

2021/01/08 01:34

その点に関しては問題ないはずです。 99%プログラムに不備があると思われます…。
jbpb0

2021/01/08 02:09

そもそも、何でimgとは別にoutを用意しているのですか? 画像から読んだデータをimgに入れたのだから、そのimgを触って(部分的に消すとか)、その後もimgをファイルに書き込めばいいのでは?? 触ってない元のデータを残したい、という意図ですか? もしそうなら、imgの内容をoutにまずコピーしないと outを触るのは、それから
sigure666

2021/01/08 02:58

>> そもそも、何でimgとは別にoutを用意しているのですか? ご想像の通り、元のデータを残したい、という意図があるからです。 imgの内容をoutにコピーですか。 試してみます。
jbpb0

2021/01/08 03:00

コピーしなくてもoutにimgと同じものが入ってる、なんて都合のいいことは起きません (outとimgは実は同じものでした、ってことをしない限り)
sigure666

2021/01/08 06:23

確かに言われてみればそうですね。 大変勉強になりました。 ありがとうございます。
guest

回答2

0

C言語のコードを書くなら、デバッグできる環境を整えましょう。
Eclipseや、WindowsならVisualStudioなど。
コードの任意の場所で実行を止め、変数のナカミを見ることができます。そこから1行づつ実行して、コードの流れを見れるようになります
そうすれば、アテズッポでコードを書かなくて済むようになります。

投稿2021/01/07 23:45

y_waiwai

総合スコア88038

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

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

0

ベストアンサー

それぞれの関数で何をしているか(入力は何、出力は何)、ちゃんと把握してみてください。

read_image("in.bmp");
imgに画像を読み込む
erase(...)
outの一定範囲を黒く塗りつぶす
write_image("out.bmp");
outを書き出す

これで「imgの一部が黒く塗り潰される」ことが期待できるでしょうか...

投稿2021/01/07 22:02

thkana

総合スコア7703

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

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

sigure666

2021/01/07 23:24

すみませんどういう意味でしょうか…?
thkana

2021/01/07 23:36

imgという紙(変数)とoutという紙(変数)を用意しました imgに絵を描きました outの真ん中を黒く塗りました outの紙をみてもimgに描いてある絵が見えません あたりまえでしょう? imgとoutは別の紙(変数)なんだから。
thkana

2021/01/07 23:41

グローバル変数は特に指定しないと初期値0になるので紙と違って何も描かない状態で「真っ黒」というのはありますけれど。
sigure666

2021/01/08 01:22

なるほど…何となく意味は掴めた気がします。 ということはeraseの処理にimgとoutを重ねるような処理を行えば良いのですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問