コード:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
#include <cstdio>
#include <windows.h>
#define sscanf_s sscanf
#define buffer line
using namespace std;
struct imageFile
{
int width, height;
};
struct RGB
{
BYTE red, green, blue;
};
imageFile ppmRead(const char *FileName);
void bmpCreate(const char *FileName, imageFile ppm);
void InitBitmapFileHeader(BITMAPFILEHEADER *fileHeader, int width, int height);
void InitBitmapInfoHeader(BITMAPINFOHEADER *infoHeader, int width, int height);
void InitBitmapHeader(BITMAPFILEHEADER *fileHeader, BITMAPINFOHEADER *infoHeader, int width, int height);
void WriteBitmapHeader(FILE *fp, BITMAPFILEHEADER fileHeader, BITMAPINFOHEADER infoHeader);
void WriteBitmapLine(FILE *fp, imageFile ppm);
//画像データ
RGB images[1050][1050];
int main(void)
{
imageFile ppm;
//ppm読み込み
ppm = ppmRead("test.ppm");
bmpCreate("test.bmp", ppm);
return 0;
}
imageFile ppmRead(const char *FileName)
{
int x, y, color;
ifstream file;
// 読み込んだ画像の解像度
int width = 0;
int height = 0;
imageFile ppm;
// 読み込んだ画像の諧調数
int max_gray = 0;
file.open(FileName ,file.in | file.binary);
// 画像の形式の取得
string line;
getline(file, line);
// 画像の解像度の取得
while ( width == 0 || height == 0 )
{
string line;
getline(file, line);
//コメント行を飛ばす
if ( line.at(0) != '#' )
{
sscanf_s( line.c_str(), "%d %d", &width, &height );
}
}
ppm.width = width;
ppm.height = height;
// 画像の諧調数の取得
while (max_gray == 0)
{
std::string line;
std::getline(file, line);
if ( buffer[0] != '#' )
{
sscanf_s( line.c_str(), "%d", &max_gray );
}
}
// 画像データの取得
for(y=0; y<height; y++)
{
for(x=0; x<width; x++)
{
file.read(reinterpret_cast<char*>(&images[x][y].red), 1);
file.read(reinterpret_cast<char*>(&images[x][y].green), 1);
file.read(reinterpret_cast<char*>(&images[x][y].blue), 1);
}
}
/*
printf("line = %s\n",line.c_str());
printf("width = %d, height = %d\n",width, height);
printf("max_gray = %d\n", max_gray);
puts("image data (press key):");
getchar();
for(y=0;y<height;y++)
{
for(x=0;x<width;x++)
{
if(x+1==width)
{
printf("%3d %3d %3d\n", images[x][y].red, images[x][y].green, images[x][y].red);
}
else
{
printf("%3d %3d %3d ", images[x][y].red, images[x][y].green, images[x][y].red);
}
}
}
*/
return ppm;
}
//BMPファイルに書き出す
void bmpCreate(const char *FileName, imageFile ppm)
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
FILE *fp = fopen(FileName, "wb");
imageFile FileData = ppm;
InitBitmapHeader(&fileHeader, &infoHeader, FileData.width, FileData.height); // ヘッダを作成
WriteBitmapHeader(fp, fileHeader, infoHeader); // ヘッダを出力
WriteBitmapLine(fp, FileData);
fclose(fp);
}
//BITMAPFILEHEADERを引数に従って初期化
void InitBitmapFileHeader(BITMAPFILEHEADER *fileHeader, int width, int height)
{
int headerSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // BITMAPINFOHEADERと共に使用されることを前提
fileHeader->bfType = 'B' + 'M' * 0x100;
fileHeader->bfSize = width * height * 3 + headerSize;
fileHeader->bfReserved1 = fileHeader->bfReserved2 = 0;
fileHeader->bfOffBits = headerSize;
}
//BITMAPINFOHEADERを引数に従って初期化
void InitBitmapInfoHeader(BITMAPINFOHEADER *infoHeader, int width, int height)
{
memset(infoHeader, 0, sizeof(BITMAPINFOHEADER));
infoHeader->biSize = 40;
infoHeader->biWidth = width;
infoHeader->biHeight = height;
infoHeader->biPlanes = 1;
infoHeader->biBitCount = 32; // true color(4byte)
}
//BITMAPFILEHEADERとBITMAPINFOHEADERを引数に従って初期化
void InitBitmapHeader(BITMAPFILEHEADER *fileHeader, BITMAPINFOHEADER *infoHeader, int width, int height)
{
InitBitmapFileHeader(fileHeader, width, height);
InitBitmapInfoHeader(infoHeader, width, height);
}
//ビットマップヘッダをファイルに書き出す
void WriteBitmapHeader(FILE *fp, BITMAPFILEHEADER fileHeader, BITMAPINFOHEADER infoHeader)
{
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
}
//RGBデータをファイルに出力
void WriteBitmapLine(FILE *fp, imageFile ppm)
{
BYTE padding = 0;
for (int y = 0; y < ppm.height; y++)
{
for (int x = 0; x < ppm.width; x++)
{
fwrite(&images[x][y].blue, sizeof(BYTE), 1, fp);
fwrite(&images[x][y].green, sizeof(BYTE), 1, fp);
fwrite(&images[x][y].red, sizeof(BYTE), 1, fp);
fwrite(&padding, sizeof(BYTE), 1, fp);
}
}
}