C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: GetHbitmap()実行によるGDIエラーの対処方法


(過去ログ 105 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■62625 / inTopicNo.1)  GetHbitmap()実行によるGDIエラーの対処方法
  
□投稿者/ コウ (13回)-(2011/10/22(Sat) 17:31:37)

分類:[C#] 

2011/10/23(Sun) 15:50:26 編集(投稿者)
2011/10/23(Sun) 15:50:14 編集(投稿者)

はじめまして^^

C#、C初心者のコウと申します。

C#、Cにて画像処理の開発をしております。
以下の処理を100ミリ秒などの間隔で繰返し処理をすると242回目で以下のエラーが発生致しました。
1回の実行では正常に動作するのですが、連続して何度も処理を実行した場合に発生するエラーです。
改善方法をご存知の方がいらっしゃいましたら、アドバイス頂けますと幸いです。
お手数をおかけ致しますが、宜しくお願い致します。


■処理
unsafe public bool LoadNumBmp()
{
bool bResult = true;
//------------------------------------------------------------------------------
// ビットマップファイルからビット配列を取り出す
//------------------------------------------------------------------------------
// --- ビットマップファイル数分ループ -----------------------------
for (int i = 0; i < _FineNames.Length; i++)
{
// ビットマップファイル読込
FileStream fs = File.OpenRead(_FineNames[i]);
Image img = Image.FromStream(fs, false, false);
_aSize[i].Width = img.Width;
_aSize[i].Height = img.Height;
// DIBバッファ生成
_aBmpBuf[i] = WinAPI.HeapAlloc(WinAPI.GetProcessHeap(), WinAPI.HEAP_ZERO_MEMORY, (UInt32)(img.Width * img.Height * 4));
WinAPI.BITMAPINFO bmpInfo;
bmpInfo.bmiHeader.biSize = (UInt32)sizeof(WinAPI.BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = img.Width;
bmpInfo.bmiHeader.biHeight = img.Height * -1; // 上下反転してない見た目通りにする
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = WinAPI.BI_RGB;
// Graphicsの作成
Graphics g = Graphics.FromImage(img);
// Graphicsのデバイスコンテキストを取得
IntPtr hDC = g.GetHdc();
Bitmap bmp = (Bitmap)img;
IntPtr hBitmap = bmp.GetHbitmap();
// DDB→DIB変換
int nLen = WinAPI.GetDIBits(hDC, hBitmap, 0, (UInt32)img.Height, _aBmpBuf[i], new IntPtr(&bmpInfo), WinAPI.DIB_RGB_COLORS);
//解放
WinAPI.DeleteObject(hBitmap);
g.ReleaseHdc(hDC);
g.Dispose();
img.Dispose();
fs.Dispose();
bmp.Dispose();
}
// --- RGB値以外の箇所を0埋め ---------------------------------------
for (int nNum = 0; nNum < _NumCount; ++nNum)
{
UInt32* lpNum = (UInt32*)_aBmpBuf[nNum];
int y = 0;
int numcy = _aSize[nNum].Height;
int numcx = _aSize[nNum].Width;
_aFirstNumPos[nNum].X = -1;
_aFirstNumPos[nNum].Y = -1;
// --- 最初に数値文字の位置 -------------------------------------
for (y = 0; y < numcy; ++y)
{
int x;
for (x = 0; x < numcx; ++x)
{
UInt32 bmpBit = lpNum[x + y * numcx] & 0xFFFFFF;
lpNum[x + y * numcx] = bmpBit;
}
}
}
return bResult;
}

■エラー
□エラー発生箇所
IntPtr hBitmap = bmp.GetHbitmap();

□エラー詳細
System.Runtime.InteropServices.ExternalException はハンドルされませんでした。
Message="GDI+ で汎用エラーが発生しました。"
Source="System.Drawing"
ErrorCode=-2147467259
引用返信 編集キー/
■62626 / inTopicNo.2)  Re[1]: GetHbitmap()実行によるGDIエラーの対処方法
□投稿者/ Hongliang (812回)-(2011/10/22(Sat) 19:56:11)
hBitmap を CloseHandle したり hDC を DeleteObject したり FileStream や Image を Dispose してなかったりといくつか突っ込みどころはありますが。
単にピクセルデータが欲しいだけなら、Bitmap クラスに LockBits メソッドが用意されていますよ?

// 分類が C/C++ の割に、質問に関わるところは C# オンリーのような気が……。
引用返信 編集キー/
■62635 / inTopicNo.3)  Re[2]: GetHbitmap()実行によるGDIエラーの対処方法
□投稿者/ コウ (14回)-(2011/10/23(Sun) 17:18:05)
No62626 (Hongliang さん) に返信
アドバイスありがとうございます^^

> hBitmap を CloseHandle したり hDC を DeleteObject したり FileStream や Image を Dispose してなかったりといくつか突っ込みどころはありますが。
ご指摘頂きました部分を修正した所、かなり改善し10万回程度ループした際に同様のエラーが発生しました。
また、実行回数が増えるにしたがって、exeで使用しているメモリ使用量が増加(GCなし)しました。
あくまで、予想ですが、exeで使用しているメモリ使用量が増加しなければ、このようなエラーは発生しないと考えており、
exeで使用するメモリ使用量が増加しない方法について、もし、何かしらご存知でしたら、アドバイス頂けますと幸いです。

> 単にピクセルデータが欲しいだけなら、Bitmap クラスに LockBits メソッドが用意されていますよ?
アドバイスありがとうございます^^
処理速度の関係上、今のロジックのままですすめたいと考えています。

> // 分類が C/C++ の割に、質問に関わるところは C# オンリーのような気が……。
C#に変更致しました。


引用返信 編集キー/
■62638 / inTopicNo.4)  Re[3]: GetHbitmap()実行によるGDIエラーの対処方法
□投稿者/ Hongliang (813回)-(2011/10/23(Sun) 22:08:39)
> また、実行回数が増えるにしたがって、exeで使用しているメモリ使用量が増加(GCなし)しました。
HeapFree してないとかありませんか?
// 何を指して「メモリ使用量」って言うのか、GCなしってのがどういう意味なのか。

>>単にピクセルデータが欲しいだけなら、Bitmap クラスに LockBits メソッドが用意されていますよ?
> アドバイスありがとうございます^^
> 処理速度の関係上、今のロジックのままですすめたいと考えています。
手元の環境ではむしろ LockBits を使った方が速いぐらいなんですけど。
引用返信 編集キー/
■62641 / inTopicNo.5)  Re[4]: GetHbitmap()実行によるGDIエラーの対処方法
□投稿者/ コウ (15回)-(2011/10/23(Sun) 23:50:14)
No62638 (Hongliang さん) に返信
アドバイスありがとうございます^^

>>また、実行回数が増えるにしたがって、exeで使用しているメモリ使用量が増加(GCなし)しました。
> HeapFree してないとかありませんか?
HeapFreeはしていませんでしたので、追加させて頂きます。

> // 何を指して「メモリ使用量」って言うのか、GCなしってのがどういう意味なのか。
タスクマネージャーのメモリ使用量や仮想メモリサイズを確認し、それをメモリ使用量と記載させて頂いています。
また、GCなしと記載させて頂きましたので、メモリ使用量が減らなかったため、GCなしと記載しています。

> >>単にピクセルデータが欲しいだけなら、Bitmap クラスに LockBits メソッドが用意されていますよ?
> 手元の環境ではむしろ LockBits を使った方が速いぐらいなんですけど。
そうなんですね。
検討させて頂きます^^

メモリ使用量の問題につきましては、記載させて頂きましたソース以外の部分にも問題がありそうですので、再度見直し、それでも改善しなかった場合に掲示板に書き込みさせて頂きたいと思います^^

色々とご親切にアドバイス頂きまして、誠にありがとうございました<(__)>
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -