StretchBltを使いミラーリングを行っているのですが、エラーが発生してしまいます。
元画像は、1BitBmpを使用し、10757x10077Pixelの画像なのですが、これよりも小さい画像では、成功します。
画像サイズに影響されず、1BitBmp画像をミラーリングしたいのですが、何か方法はありませんか?
宜しくお願いします。

(記述)
StretchBlt(lngDstDc, lngSx, lngSy, lngWidth, lngHeight, lngSrcDc, 0&, 0&, udtBmpData.bmWidth, udtBmpData.bmHeight, SRCCOPY)
lngDstDC:変換後のデバイスコンテキスト
lngSx:変換後の始点X(値:10756)
lngSy:変換後の始点Y(値:0)
lngWidth:変換後の幅(値:-10757)
lngHeight:変換後の高さ(値:10077)
lngSrcDC:変換前のデバイスコンテキスト
0&:変換前の始点X(値:0)
0&:変換前の始点Y(値:0)
udtBmpData.bmWidth:変換前の幅(値:-10757)
udtBmpData.bmHeight:変換前の高さ(値:10077)

A 回答 (1件)

 こんばんは。


 GetDIBits()APIでイメージのバッファへつまみ出してから、左右反転処理をかけて、::SetDIBitsToDevice()APIで描写すれば10757x10077Pixelでも出来る筈です。
 大分汚いコードなのですが、参考程度に。

//1スキャン辺りのバイト長を4のn倍調整で計算
static DWORD CalcScanLineByte(const DWORD w, const DWORD bpp)
{
return ((((bpp * w) + 31) / 32) * 4);
}

//pのxに対応した位置から色彩valを取ってくる
static BYTE GetLowerPixel(const LPBYTE p, DWORD x, DWORD bpp)
{
const DWORD dwBitDiff= 8 / bpp;
const DWORD dwBitCycle= (dwBitDiff - 1) - (x % dwBitDiff);
const BYTE fMask= (1 << bpp) - 1;
const INT pos= x / dwBitDiff;
const INT shr= bpp * dwBitCycle;
const BYTE val= fMask & (p[pos] >> shr);
return val;
}

//pのxに対応した位置へ色彩valを置く
static VOID SetLowerPixel(LPBYTE p, DWORD x, DWORD bpp, BYTE val)
{
const DWORD dwBitDiff= 8 / bpp;
const DWORD dwBitCycle= (dwBitDiff - 1) - (x % dwBitDiff);
const BYTE fMask= (1 << bpp) - 1;
const INT pos= x / dwBitDiff;
const INT shl= bpp * dwBitCycle;

if(val == 0)
p[pos] &= ~(1 << shl);
else
p[pos] |= (1 << shl);
}

//1bitイメージの左右反転
static VOID MonoReverse(LPBYTE pOut, const BITMAPINFO& bmi)
{
//次の行へ改行する為に必要なバイトサイズを取る
const DWORD dwStride= ::CalcScanLineByte(bmi.bmiHeader.biWidth, bmi.bmiHeader.biBitCount);
for(int y = 0; y < bmi.bmiHeader.biHeight; ++y)
for(int xLeft = 0, xRight = bmi.bmiHeader.biWidth - 1; xLeft < bmi.bmiHeader.biWidth / 2; ++xLeft, --xRight)
{
//ラインの先頭
LPBYTE pLine = &pOut[y * dwStride];
//左側の色彩
const BYTE colorLeft = ::GetLowerPixel(pLine, xLeft, bmi.bmiHeader.biBitCount);
//右側の色彩
const BYTE colorRight= ::GetLowerPixel(pLine, xRight, bmi.bmiHeader.biBitCount);
//色彩の入れ替え
::SetLowerPixel(pLine, xLeft, bmi.bmiHeader.biBitCount, colorRight);
::SetLowerPixel(pLine, xRight, bmi.bmiHeader.biBitCount, colorLeft);
}
}

//1BitDIBのヘッダ設定
static VOID InitMonoBIH(BITMAPINFOHEADER& bih, DWORD dwWidth, DWORD dwHeight)
{
bih.biSize = sizeof(bih);
bih.biBitCount = 1;
bih.biClrUsed = 1 << bih.biBitCount;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biWidth = dwWidth;
bih.biHeight = dwHeight;
}

//ミラーリング
static BOOL DrawMirror(HDC hDCDest, LONG x, LONG y, HBITMAP hBitmap)
{
BITMAP bitmap;
::GetObject(hBitmap, sizeof(bitmap), &bitmap);

BITMAPINFO bmi = {0};
::InitMonoBIH(bmi.bmiHeader, bitmap.bmWidth, bitmap.bmHeight);

if(::GetDIBits(hDCDest, hBitmap, 0, bitmap.bmHeight, NULL, &bmi, DIB_RGB_COLORS) == 0)
return FALSE;

HGLOBAL hMem = ::GlobalAlloc(GMEM_FIXED, bmi.bmiHeader.biSizeImage);
LPBYTE pBuffer = (LPBYTE)::GlobalLock(hMem);

if(::GetDIBits(hDCDest, hBitmap, 0, bitmap.bmHeight, pBuffer, &bmi, DIB_RGB_COLORS) == 0)
return FALSE;

::MonoReverse(pBuffer, bmi);

::SetDIBitsToDevice(hDCDest, x, y, bitmap.bmWidth, bitmap.bmHeight, 0, 0, 0, bitmap.bmHeight, pBuffer, &bmi, DIB_RGB_COLORS);

::GlobalUnlock(hMem);
::GlobalFree(hMem);

return TRUE;
}

//
// ::DrawMirror(hDC/*変換先*/, 0/*x位置*/, 0/*y位置*/, hBitmap/*変換元*/);
// でhDCに向かってモノクロイメージを反転描写
    • good
    • 0
この回答へのお礼

お礼が遅くなってすいませんでした。
回答ありがとうございました。
早速確認を行ってみます。

お礼日時:2009/05/29 09:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


人気Q&Aランキング