[BMP]ビットマップの編集 | Assertion Failed!

[BMP]ビットマップの編集

編集と呼ぶには程遠いけど


前回 表示した赤塗りつぶしビットマップデータと、以下の画像を重ねてみる。


Assertion Failed!

[作成環境]

・Visual Studi 2008 Standart Edition

・MFC-ダイアログベース


ダイアログクラスに以下のメンバを新に追加


private:

  CBitmap m_bmp; // 背景

  CBitmap m_img; // 画像(新規追加)


OnInitDialog()


// TODO: 初期化をここに追加します。


// ビットマップ背景データ部分を作成(高さ200px、幅300px)

BYTE *pData = new BYTE[200*300*4];


// 背景データ部分の初期化

for(int i = 0; i < 200*300*4; i += 4)

{

  pdata[i]  = 0x00; // 青成分

  pdata[i+1] = 0x00; // 緑成分

  pdata[i+2] = 0xFF; // 赤成分

  pdata[i+3] = 0x00; // 未使用(予約領域)

}


// 画像ビットマップのロード

HBITMAP hbmp = (HBITMAP)LoadImage(0,

                           _T("C:\\sample.bmp"),

                           IMAGE_BITMAP,

                           0,

                           0,

                           LR_LOADFROMFILE);


// 取得したハンドルからビットマップオブジェクトを作成

m_img.Attach(hbmp);


// BITMAP構造体の取得

BITMAP bm;

m_img.GetBitmap(&bm);


// 高さと幅の取得

int iWidth = bm.bmWidth;

int iHeight = bm.bmHeight;


int size = iWidth * iHeight * 4;


// 画像データ領域バッファ確保

BYTE *pImg = new BYTE[ size ];


// 確保したバッファに画像データを格納

m_img.GetBitmapBits(size, pImg);


// 背景領域に画像データを上書き

int i,j;

for(i = 0; i < iHeight; i++)

{

  for(j = 0; < iWidth * 4; j++)

  {

    pData[j + i * 300 * 4] = pImg[j + i * iWidth * 4];

  }

}


// ビットマップの作成

m_bmp.CreateCompatibleBitmap(GetDC(), 300, 200);


// 作成したビットマップに、作成したデータ部分をセット

m_bmp.SetBitmapBits(200*300*4, pData);


delete [] pData;

delete [] pImg;


// Attachした画像はOnDestroy()内とか不要になった時点でDetach


OnPaint()


変更なし



結果


Assertion Failed!-ビットマップ編集


ちょっとした説明

pData[j + i * 300 * 4] = pImg[j + i * iWidth * 4];


前回も少し書いたが、ビットマップデータ部として1次元配列として確保している。


その中で特定の座標(x, y)を取り出すためには


先頭アドレスに (x + y * (幅))のオフセットを与えればよい。

(1ピクセルの表現にRGBQUADで4バイト要するので×4も行っている)


背景と画像では幅が違うので、折り返し位置を正しく表現したいために

今回の方法をとった。


多分もっとよいやり方はあると思う。


あくまで動作を知るためのコードということで。