【C言語】第10章第11回:C言語での画像処理プログラム
本記事では、C言語を使用して画像処理を行うプログラムを作成します。BMP画像の読み込み、グレースケール変換、保存の基本を学びます。
0. 記事の概要
この記事を読むメリット
- 画像処理の基礎理解:画像データの構造や編集方法を学べます。
- 実践的なプログラム作成:画像を操作するスキルを身につけ、実用的なツール開発につなげられます。
- 応用力の向上:学んだ技術を応用して、画像フィルタリングやエフェクトの作成が可能になります。
この記事で学べること
- BMP画像の基本構造
- 画像の読み込みと編集方法
- グレースケール変換の実装
1. 画像処理プログラムの基本設計
1.1 BMP画像の基本構造
BMP画像は以下の部分で構成されています。
- ファイルヘッダー(ファイルサイズや画像の開始位置を記録)
- 情報ヘッダー(画像の幅、高さ、色深度などを記録)
- ピクセルデータ(画像の各ピクセルの色情報を格納)
1.2 プログラムの機能
このプログラムでは以下の基本機能を実装します。
- BMP画像の読み込み
- グレースケール変換
- 変換結果の保存
2. コード例と詳細解説
2.1 基本コード例
#include <stdio.h>
#include <stdlib.h>
#pragma pack(1) // 構造体のパディングを無効化
typedef struct {
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
} BMPFileHeader;
typedef struct {
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BMPInfoHeader;
void convertToGrayscale(unsigned char *pixelData, int width, int height) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width * 3; j += 3) {
unsigned char r = pixelData[i * width * 3 + j + 2];
unsigned char g = pixelData[i * width * 3 + j + 1];
unsigned char b = pixelData[i * width * 3 + j];
unsigned char gray = (r + g + b) / 3;
pixelData[i * width * 3 + j] = gray;
pixelData[i * width * 3 + j + 1] = gray;
pixelData[i * width * 3 + j + 2] = gray;
}
}
}
int main() {
FILE *file = fopen("input.bmp", "rb");
if (!file) {
perror("ファイルを開けませんでした");
return 1;
}
BMPFileHeader fileHeader;
BMPInfoHeader infoHeader;
fread(&fileHeader, sizeof(BMPFileHeader), 1, file);
fread(&infoHeader, sizeof(BMPInfoHeader), 1, file);
unsigned char *pixelData = malloc(infoHeader.biSizeImage);
fseek(file, fileHeader.bfOffBits, SEEK_SET);
fread(pixelData, 1, infoHeader.biSizeImage, file);
fclose(file);
convertToGrayscale(pixelData, infoHeader.biWidth, infoHeader.biHeight);
FILE *output = fopen("output.bmp", "wb");
if (!output) {
perror("出力ファイルを作成できませんでした");
return 1;
}
fwrite(&fileHeader, sizeof(BMPFileHeader), 1, output);
fwrite(&infoHeader, sizeof(BMPInfoHeader), 1, output);
fwrite(pixelData, 1, infoHeader.biSizeImage, output);
fclose(output);
free(pixelData);
printf("グレースケール変換が完了しました!\\n");
return 0;
}
動作解説
- 画像の読み込み:BMPファイルのヘッダー情報を読み取り、ピクセルデータをメモリに格納します。
- グレースケール変換:各ピクセルのRGB値を平均してグレースケール化します。
- 変換結果の保存:編集済みのピクセルデータを新しいBMPファイルに書き込みます。
3. 練習問題
以下の課題に挑戦して、画像処理プログラムを拡張してみましょう。
- 画像を反転させる機能を追加してください。
- 指定された領域だけをグレースケール化する機能を追加してください。
- 画像を回転させる機能を実装してください。
4. 練習問題の解答と解説
問1の解答例
// 画像を反転させるロジック
void invertImage(unsigned char *pixelData, int width, int height) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width * 3; j += 3) {
unsigned char tempR = pixelData[i * width * 3 + j + 2];
unsigned char tempG = pixelData[i * width * 3 + j + 1];
unsigned char tempB = pixelData[i * width * 3 + j];
pixelData[i * width * 3 + j + 2] = 255 - tempR;
pixelData[i * width * 3 + j + 1] = 255 - tempG;
pixelData[i * width * 3 + j] = 255 - tempB;
}
}
}
この関数では、RGB値を255から減算して各ピクセルを反転させます。
5. まとめ
本記事では、C言語を用いてBMP画像の読み込み、編集、保存を行うプログラムを作成しました。さらに高度な処理を加え、画像処理ツールを拡張してみましょう。