今回は、BMP画像の表示について少し行き詰っている部分があるのでアドバイスなどを与えてくれれば幸いです。
環境
OS:Windows 8.1
Compiler:VC++
Library:DXライブラリ
今、プログラミングでの画像についての扱いなどで、折角だし簡易的な圧縮でも試してみようかと、初めに
手動によるBMP画像の読み込み、二値化やグレースケール化などを行っています。
とりあえず基本的にできたと思っていたのですが、表示が若干おかしくなってしまいます。
元の画像がコレ
で、
私が組んだプログラムで表示させたモノが
です。
なんというか、ところどころに左に90度回転させたかのように引き伸ばされた画像がうっすらと見えるような点が
打たれてしまっています。
なお、今回私が組んだプログラムの大部分はこのサイト様のこちらのページを参考にさせていただいています。
以下ソースコード
(無駄に分割されていて見づらいかもしれませんがよろしくお願いします。)
Main.cpp
#include "DxLib.h"
#include "BMPMgr.h" //マネージャーのinclude
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
ChangeWindowMode(TRUE), SetDrawScreen(DX_SCREEN_BACK), DxLib_Init();
BMPMgr_Load(); //読み込みさせて
BMPMgr_Convert(); //変換させて
while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
BMPMgr_Draw(); //描画
ScreenFlip();
}
DxLib_End();
return 0;
}
BMPmgr.h
//多重インクルード防止
#ifndef DEF_BMPMGR_H
#define DEF_BMPMGR_H
bool BMPMgr_Load();
void BMPMgr_Convert();
void BMPMgr_Draw();
#endif
BMPmgr.cpp
#include "DxLib.h"
#include "BMP.h"
//描画するオブジェクトの量
static const int NUM = 1;
//画像サイズ分の量のデータ確保
unsigned char data[TOTAL];
//オブジェクト分のイメージ情報を確保
img_t img[NUM];
//現在は使っていない
//bool Pixel[BMP_WEIGHT][BMP_HEIGHT];
//ロードさせる
bool BMPMgr_Load()
{
for (int i = 0; i < NUM; i++)
{
//描画に失敗すればfalseを返す
if (BMP_Load(&data[TOTAL])) return false;
}
return true;
}
//変換させる
void BMPMgr_Convert()
{
for (int i = 0; i < NUM; i++)
{
BMP_Convert(&img[i],&data[TOTAL]);
}
}
//描画させる
void BMPMgr_Draw()
{
for (int i = 0; i < NUM;)
{
BMP_Draw(&img[i],GLAY);
i++;
}
}
BMP.h
//多重インクルード防止
#ifndef DEF_BMP_H
#define DEF_BMP_H
//いろいろ定数を宣言
#define BMP_HEADER 54 //ヘッダの大きさ(54byte)
//とりあえず画像サイズは固定、ヘッダも無視する
#define BMP_WEIGHT 640
#define BMP_HEIGHT 480
#define BMP_BLACKORWHITE 128 //白と黒に分ける場合の境目
#define TOTAL (BMP_WEIGHT * BMP_HEIGHT * 3 + BMP_HEADER) //読み込むべきサイズ
//モードの宣言
enum
{
MONO,
GLAY,
FULL,
};
//一つのピクセルが持つ情報
typedef struct
{
unsigned char color[3];
}pixel_t;
//一つの画像が持つ情報
typedef struct
{
//画素を画像の大きさ分確保
pixel_t pixel[BMP_WEIGHT][BMP_HEIGHT];
}img_t;
//ロードさせる関数
bool BMP_Load(unsigned char data[TOTAL]);
//扱いやすいように変換する関数
void BMP_Convert(img_t *img,unsigned char data[TOTAL]);
//描画させる関数
void BMP_Draw(img_t *img,int MODE);
#endif DEF_BMP_H
BMP.cpp
たぶんこれが問題
#include "DxLib.h"
#include "BMP.h"
//あらかじめ白と黒は宣言しておく
int black = GetColor(0, 0, 0);
int white = GetColor(255, 255, 255);
//画像のロード
bool BMP_Load(unsigned char data[TOTAL])
{
char name[256] = "BMP.bmp"; //画像の名前
FILE *fp; //ファイルの構造体
fp = fopen(name, "rb"); //読み込み
if (fp == NULL) //失敗すれば
{
printfDx("%sが見つかりませんでした", name);
fclose(fp); //閉じて
return false; //falseを返す
}
fread(data, TOTAL, 1, fp); //そうでなければロードさせる
fclose(fp); //閉じて
return true; //終了
}
//データを扱いやすく変換
void BMP_Convert(img_t *img,unsigned char data[TOTAL])
{
int x, y, c, t;
t = BMP_HEADER;
//y方向へのロード
for (y = BMP_HEIGHT - 1; y >= 0; y--)
{
//x方向へのロード
for (x = 0; x < BMP_WEIGHT; x++)
{
//RGB分ロード
for (c = 0; c < 3; c++)
{
img->pixel[x][y].color[c] = data[t]; //ヘッダ以降のデータを実際に代入
t++; //次のデータにイクリメント(unsigned char分足す)
}
}
}
}
//描画
void BMP_Draw(img_t *img,int MODE)
{
int x, y;
//y方向へ描画
for (y = BMP_HEIGHT - 1; y >= 0; y--)
{
//x方向へ描画
for (x = 0; x < BMP_WEIGHT; x++)
{
//モードによって異なる描画方法
switch (MODE)
{
case FULL:
DrawPixel(x, y, GetColor(img->pixel[x][y].color[2], img->pixel[x][y].color[1], img->pixel[x][y].color[0]));
break;
case GLAY:
DrawPixel(x, y, GetColor(img->pixel[x][y].color[0], img->pixel[x][y].color[0], img->pixel[x][y].color[0]));
break;
case MONO:
//RGBの平均値が黒か白かの境目より大きければ
if (img->pixel[x][y].color[2] + img->pixel[x][y].color[1] + img->pixel[x][y].color[0] / 3 > BMP_BLACKORWHITE)
DrawPixel(x, y, white); //白く描画
else //そうでなければ
DrawPixel(x, y, black); //黒く描画
break;
}
}
}
}
突っ込みどころしかないかもしれませんが、よろしくお願いします。
突っ込むところがあればどんどん突っ込んでくれれば幸いです。
何も触っていない(ハズ)にもかかわらず、動作がかなり変化してしまいました。
※コメントをつける作業と BMPmgr.cppの40行目をGLAYからFULLに変更。ただしGLAYに戻しても戻らず。
加えて終了時に「XXXXは動作を終了しました」の表示
実行中にOSの動きが不安定になることから大分致命的なミス?