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

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

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

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

受付中

bmp画像のグレースケール化

k.s.4096
k.s.4096

総合スコア0

C

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

1回答

0評価

0クリップ

296閲覧

投稿2022/07/31 10:10

前提

bmp画像を入力し、出力画像をグレースケールにしたいです。

実現したいこと

・構造体としてファイルヘッダ、情報ヘッダを定義する(情報ヘッダから画像の縦横サイズを取得するため)
・bmp画像を入力する
・メモリの空き領域を確保する(malloc関数)
・色を変換したピクセルごと(RGB)のデータを書き込む
・bmp画像をグレースケールにて出力する

発生している問題・エラーメッセージ

エラーメッセージは出力されておらず、画像は出力されています。ただ、グレースケールではなくカラーのままです。おそらく、書き込みにおけるforループの方法が間違っており、最初の1行目のみグレースケールになっている可能性が高いです。(バイナリエディタにて確認済み)

該当のソースコード

#include <stdio.h> #include <stdlib.h> #pragma pack(push,1) /*ファイルヘッダを表す構造体*/ typedef struct{ char cType[2]; unsigned long ulSize; unsigned short usReserved1; unsigned short usReserved2; unsigned long ulOffBits; } FILE_HEADER; /*情報ヘッダを表す構造体*/ typedef struct{ unsigned long ulSizeINFO; unsigned long ulWidth; //横のピクセル数 unsigned long ulHeight; //縦のピクセル数 unsigned short usPlanes; unsigned short usBitCount; unsigned long ulCompression; unsigned long ulSizeImage; unsigned long ulPixPerMeter1; unsigned long ulPixPerMeter2; unsigned long ulClrUsed; unsigned long ulClrImportant; } INFO_HEADER; #pragma pack(pop) int main(void) { FILE_HEADER st_fileheader = {0}; INFO_HEADER st_infoheader = {0}; FILE *infp, *outfp; char infile[FILENAME_MAX], outfile[FILENAME_MAX]; unsigned char *puc_image = NULL; unsigned long ul_width = 0; size_t ll_ans1, ll_ans2, ll_ans3 = 0; int i, j; unsigned char gray; /*読み込み*/ if ((infp = fopen("100.bmp", "rb")) == NULL) { printf("ファイル読み込み失敗しました。\n"); } else{ ll_ans1 = fread(&st_fileheader, 1, sizeof(st_fileheader),infp); //ファイルヘッダの読み込み ll_ans2 = fread(&st_infoheader, 1, sizeof(st_infoheader),infp); //情報ヘッダの読み込み ul_width = (((st_infoheader.ulWidth * 3) + 3) / 4) * 4; //bmpなので横方向のピクセル数を4の倍数に変換 puc_image = (unsigned char*)malloc(sizeof(unsigned char) * ul_width * st_infoheader.ulHeight); //画像部分のメモリを解放 if(puc_image != NULL){ ll_ans3 = fread(puc_image, 1, ul_width * st_infoheader.ulHeight, infp); //五臓ファイルを読み込み } else{ } } /*書き込み*/ if ((outfp = fopen("101.bmp", "wb")) == NULL) { printf("ファイル読み込み失敗しました。\n"); } else{ ll_ans1 = fwrite(&st_fileheader, 1, sizeof(st_fileheader),outfp); //ファイルヘッダの読み込み ll_ans2 = fwrite(&st_infoheader, 1, sizeof(st_infoheader),outfp); //情報ヘッダの読み込み if(puc_image != NULL){ for (j = 0; j < st_infoheader.ulHeight ; j++){ for (i = 0; i < ul_width; i += 3){ gray = (unsigned char)(0.114 *(double)puc_image[i]) +(0.299 * (double)puc_image[i + 1] + 0.587 * (double)puc_image[i + 2]); //各ピクセルをグレースケール化する数式 puc_image[i] = gray; //Gのピクセルをグレースケールに置き換え puc_image[i + 1] = gray; //Bのピクセルをグレースケールに置き換え puc_image[i + 2] = gray; //Rのピクセルをグレースケールに置き換え } } //この辺が違うのではないか?? ll_ans3 = fwrite(puc_image, 1, ul_width * st_infoheader.ulHeight, outfp); } else{ fclose(outfp); } } free(puc_image); return 0; }

試したこと

書き込み欄のforループによる演算が特に間違っていると考えられます。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C

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