
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)
No.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に向かってモノクロイメージを反転描写
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- Photoshop(フォトショップ) 情報処理の画像生成の問題について 2 2023/05/05 23:56
- その他(Microsoft Office) エクセル 日付を数値に変換する方法 4 2023/03/24 12:05
- その他(プログラミング・Web制作) Python画像処理について 1 2022/05/17 17:40
- Excel(エクセル) 【至急 詳しい方教えて下さい】Excelの表を変換したい 6 2022/04/21 18:35
- 画像編集・動画編集・音楽編集 コムテックのドライブレコーダーZDR-015の録画データ(前後カメラ)を通常は専用のソフトで映像を再 1 2022/06/13 15:03
- 一眼レフカメラ 「Imaging Edge」を手動起動せず、ARWファイルを最高画質JPEGへ変換する方法は? 2 2022/08/05 11:38
- Android(アンドロイド) HEICファイルに勝手に変換される? 1 2022/12/03 06:26
- フリーソフト フリーソフト[フリーオンライン動画兼音声変換ソフト]縦長になってしまう 2 2022/07/11 08:11
- フリーソフト 倍率自動調整して全画面表示できるフリーの画像ビューアー 1 2023/08/24 10:55
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミングについて。 1つ...
-
gccを行ってもexeファイルが生...
-
c言語
-
visual studio 2022でのC#プロ...
-
C# DatagridviewにExcelシート...
-
mallocについて
-
C言語って古いですか?
-
C言語関数違いについて。
-
逆コンパイルと逆アセンブルの...
-
プログラムの実行時に'<'でリダ...
-
パソコン
-
CPUが16bitでも32bitOSでコンパ...
-
Python、プログラミングについ...
-
だれがとけるの?
-
バッチファイルで以下のような...
-
Notepad++の関数リスト表示の変...
-
VisualStudio2022でC言語プログ...
-
License='MIT' ってなんでmitな...
-
C言語 ストリームについて。
-
c言語でイベントフラグを使った...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語
-
gccを行ってもexeファイルが生...
-
大量のデータを読み込んで表示...
-
visual studio 2022でのC#プロ...
-
C++でデスクトップGUIアプリ開...
-
【C言語】全角文字の配列を、全...
-
Windows Formアプリからコンソ...
-
VisualStudio2022でC言語プログ...
-
C#でログファイルにファイルパ...
-
C#でTreeViewのCheckBoxのサイ...
-
c#のTLS1.2での通信について
-
VisualStudioでC++クラスを追加...
-
C言語について。
-
int16_t の _t は何?
-
プログラマー達は何故、プログ...
-
逆コンパイルと逆アセンブルの...
-
C言語の関数のextern宣言
-
c言語でイベントフラグを使った...
-
C言語 関数、変数の宣言について
-
[C言語]fputsとfprintfの違い
おすすめ情報