GetDIBits関数を含むプログラムの終了時におけるエラー

[戻る]
merlo 2002/04/27(土) 13:13:17
saito()様

できました!感激です.
でも,終了時にエラーが起きてしまいます

"0x77fcb9b1"の命令が"0x00000000"のメモリを参照しました.メモリが
"written"になることができませんでした.

とアプリケーションエラーが出ます.
正確には,出ていた時と出始めた時期がありました.

また,最初の方はうまくDIBITsもできていたのですが,
なぜか,途中から,StretchBltで表示すると
色が微妙におかしくなってしまいます.

以下は,RenderにてJPGを表示させているだけなのに
上述のエラーが終了時に発生してしまう
比較的シンプルなプログラムです.

ちなみに,MFC ダイアログベースです.

public:
    BYTE* m_Images;
    BITMAPINFO *m_bi;


/*□□□□□□□□□□□イニシャル関数□□□□□□□□□□
    if(m_bi!=NULL) delete[] m_bi;
    if(m_Images!=NULL) delete[] m_Images;


/*□□□□□□□□□□□ボタンの関数□□□□□□□□□□□メンバ関数
void CBMP_editDlg::OnBUTTONopen() 
{
    CSize sizeTotal;
    CPictureHolder pH;
    LPDISPATCH ld;
    OLE_HANDLE phandle;
    HBITMAP hbm;
    DIBSECTION ds;
    CString m_fullpathname;
    CDC* pDC=m_pict.GetDC();
    HDC hDC=pDC->GetSafeHdc();

    CFileDialog PathDLG
(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
        "jpeg(*.jpg)|*.jpg||");
    if(PathDLG.DoModal()!=IDOK)return;
    m_fullpathname=PathDLG.GetPathName();
    if(FAILED(::OleLoadPictureFile(COleVariant(m_fullpathname),&ld))) 
return;
    pH.SetPictureDispatch((LPPICTUREDISP)ld);
    if(pH.GetType()!=PICTYPE_BITMAP) return;
    pH.m_pPict->get_Handle(&phandle);
    hbm=(HBITMAP)phandle;
    GetObject(hbm,sizeof(DIBSECTION),&ds);
    sizeTotal.cx=ds.dsBm.bmWidth;
    sizeTotal.cy=ds.dsBm.bmHeight;

    pH.Render(pDC,&CRect(0,0,sizeTotal.cx,sizeTotal.cy),&CRect(0,0,0,0));

    m_bi=(BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)];
    m_bi->bmiHeader=ds.dsBmih;

    (void)GetDIBits(hDC,hbm,0,0,NULL,m_bi,DIB_RGB_COLORS);
    m_Images=new BYTE[m_bi->bmiHeader.biSizeImage];
    (void)GetDIBits(hDC,hbm,0,m_bi-
>bmiHeader.biHeight,m_Images,m_bi,DIB_RGB_COLORS);
    
    pH.m_pPict->Release();
    DeleteObject(hbm);
    ReleaseDC(pDC);
    ::ReleaseDC(m_hWnd,hDC);
    
}

なぜ,終了時にエラーが出てしまうのでしょうか.

追記です.

JPEG→BMP化の作業の途中でRENDERにて出力する
画像は原画と同じでとてもきれいですが,
Stretchbltで出力する画像は,色情報が壊れているみたいです.
なんと言ったらいいのでしょうか
全体的に不思議な縞々が入ります.
縦方向や横方向の伸縮表示させると
縦縞や横縞がでるのは,よくあることらしいですが
僕のは,色がおかしいです.

また,Renderでも,Stretchbltでも関係なく
終了時にエラーがでます・・・涙

int hhh=GetDIBits(hDC,hbm,0,0,NULL,m_bi,DIB_RGB_COLORS);
m_Images=new BYTE[m_bi->bmiHeader.biSizeImage];
int hh=GetDIBits(hDC,hbm,0,m_bi->bmiHeader.biHeight,
               m_Images,m_bi,DIB_RGB_COLORS);

結局↑の部分を無効にしてRender機能だけにしたら
終了時のエラーがでませんでした.
GetDIBits関数の使い方が間違っているのでしょうか.

なお,この記述は 『BitBltはPrintOutできますか?』
のsaito();様の記述をそのまま利用しただけです.

通りすがり 2002/04/27(土) 13:24:24
>saito()様

>できました!感激です.
>でも,終了時にエラーが起きてしまいます

なに?
なんかの続き?
新しいスレッドを立てる必要はある?

もし立てる必要があるとしても、どこの続きかURLを明示するべきなのでは?

merlo 2002/04/27(土) 13:44:42
すみません.
こちらのスレッドの続きです.
失礼いたしました.

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200203/02030098.txt

Bun 2002/04/27(土) 15:08:06
内容についてはわからないけど

CDC* pDC=m_pict.GetDC();
HDC hDC=pDC->GetSafeHdc();

if (条件)
  return;

ReleaseDC(pDC);
::ReleaseDC(m_hWnd,hDC);
    
で条件が真の時にreturnしちゃったらまずいでしょ。
Releaseできませんよね。

それと
m_Images=new BYTE[m_bi->bmiHeader.biSizeImage];

はどこかでdeleteしてますか?
(もちろんイニシャル関数以外で)
new と delete は一対になります。

merlo 2002/04/27(土) 15:16:06
Bun 様

アドバイスありがとうございます

>条件が真の時にreturnしちゃったらまずいでしょ。
>Releaseできませんよね。

おっしゃるとおりです.
すぐに修正します.

>new と delete は一対になります。

すぐにチェックします

merlo 2002/04/27(土) 16:20:31
[[解決]]
Bun様のご指摘に沿って,確実にReleaseされるように
プログラムを修正したら,終了時のエラーが発生しなくなりました.

また,色彩に関してですが,画面のプロパティで,解像度を変えたら,
なぜか直りました(以前までは 1280*768).

どうもありがとうございました.

ところで,ビットマップハンドルとか
OlePictureLoadとか,HDCとかに関して,
みなさまは,どちらの本で勉強されてますか?

ご紹介いただけたらと思い,追記しました.

Bun 2002/04/27(土) 17:09:21
>プログラムを修正したら,終了時のエラーが発生しなくなりました.

おめでとござんす。(^_^;

>HDCとかに関して,
>みなさまは,どちらの本で勉強されてますか?

本ぢゃないですけど、こちらはいかがでしょうか。
お金かかんないし、いろいろありまっせ〜。

http://www.sm.rim.or.jp/~shishido/

http://black.sakura.ne.jp/~third/win.html

#まず基礎が大事です、がんばってください。

merlo 2002/04/27(土) 17:50:34
Bun 様

ご紹介ありがとうございます.
書籍には,僕が知りたいことをなかなか見つけることが
できず,このラウンジに頼ってばかりでしたが
さっそく今日から勉強し直します!

(^-^)

saito( ); 2002/05/01(水) 20:29:35
はじめまして。
私もまだ、Jpeg他の画像読み込みで悩んでおります。

merloさんのソフトで以下の点が気になりました。
(BunさんのReturn以外に)

    pH.SetPictureDispatch((LPPICTUREDISP)ld);
    if(pH.GetType()!=PICTYPE_BITMAP) return;
    pH.m_pPict->get_Handle(&phandle);
    hbm=(HBITMAP)phandle;
    GetObject(hbm,sizeof(DIBSECTION),&ds);----(1)
    sizeTotal.cx=ds.dsBm.bmWidth;
    sizeTotal.cy=ds.dsBm.bmHeight;

    pH.Render(pDC,&CRect(0,0,sizeTotal.cx,sizeTotal.cy),&CRect(0,0,0,0));

    m_bi=(BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)];
    m_bi->bmiHeader=ds.dsBmih;----(3)

    (void)GetDIBits(hDC,hbm,0,0,NULL,m_bi,DIB_RGB_COLORS);----(2)
    m_Images=new BYTE[m_bi->bmiHeader.biSizeImage];
    (void)GetDIBits(hDC,hbm,0,m_bi->bmiHeader.biHeight,m_Images,m_bi,
           DIB_RGB_COLORS);
    
(1)にて、BITMAPINFOの情報は取得済みですから
(2)の処理は不要です。(これは、BITMAPINFOの一部の情報を得る為なので)
そのために、(3)を行っております。

でも、最近、気に付いたのですが、
OleLoadPicture(・・・)で読み込んだデータは
個人のパソコンの『画面』->『カラー』の設定値以下の
BitCountしか再現されていません(16とか、24(32)FullColorのうち)
[LDCに表示している分には、きれいに写りますが、PrintOutすると
 このBitCountの差がはっきり分かります]

OleLoadPicture(・・・)の実行までに
ChangeDisplaySettingsEx(・・・・)を
実行すればいいのでしょうが、ちょっと
(個人的には)おもしろくありません。

どなたか、DLLを使わずに、Jpegデータ読み込める手法を
ご存知の方、教えてください。

(CV++ではやっぱ、DLLしかないのかな〜、他の言語にて自分でDLL
作るしかないのかな〜???)

dairygoods 2002/05/01(水) 22:36:34
> どなたか、DLLを使わずに、Jpegデータ読み込める手法を
> ご存知の方、教えてください。

下記にJPEGのライブラリがあります。
http://www.ijg.org/ 

こちらも参考になるのでは。FAQの訳もあります。
http://plaza27.mbn.or.jp/~inetwada/

merlo 2002/05/02(木) 05:02:48
saito(); さんがDLL使いたくない理由なんとなく共感できます.

過去の財産を有効利用するのは,非常に大事ですが,
一部の人には自分ですべてを把握しないと気がすまないのですよね.
僕もそのうちの一人です(^-^)

でも,必要ならばDLLを使わなければならなくなると思います.

saito( ); 2002/05/02(木) 17:32:25
dairygoodsさん、merloさんありがとうございます。

さっそく調べてみます。

古いスレッドには追加発言できません。