前提
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ループによる演算が特に間違っていると考えられます。

下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2022/07/31 10:41
2022/07/31 11:01 編集