[BMP]StretchDIBits | Assertion Failed!

[BMP]StretchDIBits

DIBを拡大/縮小する。


ファイルから読み込んだファイルやCreateDIBSection で作成した

DIBを拡大/縮小するにはStretchDIBits()関数を使う。


DDBを拡大/縮小する関数としてStretchBlt()関数もあるが、汎用性を

考えるとStretchDIBitsを覚えたほうがよいと思う。


int StretchDIBits(
 HDC hdc,        // デバイスコンテキスト
 int XDest,        // 転送先開始位置x座標
 int YDest,        // 転送先開始位置y座標
 int nDestWidth,     // 転送先画像幅
 int nDestHeight,    // 転送先画像高さ
 int XSrc,         // 元画像開始位置x座標
 int YSrc,         // 元画像開始位置y座標
 int nSrcWidth,      // 元画像幅
 int nSrcHeight,     // 元画像高さ
 CONST VOID *lpBits, // 元画像イメージ
 CONST BITMAPINFO *lpBitsInfo, // 元画像BITMAPINFO構造体
 UINT iUsage,      // 色形式
 DWORD dwRop     // ラスタオペレーション
);


戻り値は、コピーした走査行(高さのこと?)が返される。



Assertion Failed!-StretchDIBits
50%に縮小


上図のように、50%縮小した際のソースはこちら。

(エラー処理などは一切考慮なし)


class CSampleDlg : public CDialog

{

private:

  // 元画像BIH

  BITMAPINFOHEADER m_bih;

  // 画像データ列格納

  BYTE *m_pImg;


  ・・・

}


BOOL CSampleDlg::OnInitDialog()
{
  ・・・中略
  CFile file(_T("C:\\Sample.bmp"), CFile::modeRead);


  BITMAPFILEHEADER bfh;
  file.Read(&bfh, sizeof(BITMAPFILEHEADER));


  file.Read(&m_bih, sizeof(BITMAPINFOHEADER));


  // イメージデータ取得

  m_pImg = new BYTE [m_bih.biSizeImage];

  file.Seek(bfh.bfOffBits, CFile::begin);
  file.Read(m_pImg, m_bih.biSizeImage);


  return TRUE;

}


void CSampleDlg::OnPaint()
{
  if (IsIconic())
  {
    ・・・中略
  }
  else
  {
    CPaintDC dc(this);


    // 幅と高さを半分にする。
    int nWidth = m_bih.biWidth / 2;
    int nHeight = m_bih.biHeight / 2;


    // 読み込んだ画像からDIBを作成する

    BYTE *pImg;
    HBITMAP hbmp = (HBITMAP)::CreateDIBSection(dc.GetSafeHdc(),

      (BITMAPINFO*)&m_bih, DIB_RGB_COLORS, (void**)&pImg, NULL, 0);

    memcpy(pImg, m_pImg, m_bih.biSizeImage);
    

    // ビットマップオブジェクトに割り当て
    CBitmap bmp;
    bmp.Attach(hbmp);


    // 拡大/縮小

    ::StretchDIBits(dc.GetSafeHdc(), 0, 0, nWidth, nHeight,
      0, 0, m_bih.biWidth, m_bih.biHeight, m_pImg,
      (BITMAPINFO*)&m_bih, DIB_RGB_COLORS, SRCCOPY);
  }
}


このように、拡大/縮小後の幅と高さを指定することで、自動的に関数内で

拡大/縮小を行ってくれる。(元画像のサイズへの比率で。)


しかし、現状のリサイズ後イメージは画像リンクを参照してもらえば

わかるように、色の割り当てが荒い。

回転の際に紹介したニアレストネイバー法 のような状態)


この画像を補間した状態で出力するためには、上記コードに

1行追加するだけでよいが、それはまた次回