VC++6を勉強し始めて間もない者です。
先日も数日悩んでいた問題点を
ここで、解決していただき
ありがたく思っております。
いま、画像表示をするVC++プログラムをMFCにて
作成中です。
このホームページでもBMP以外の表示方法に
悩んでおられる人がおおいみたいで、
その対応は『DLLを入手して・・・』と
ありましたが、著作権とか、
『フリーウェアですが他に配布する場合は・・・』
とか制約が気になります。
そこで、わたしは[CHtmlView]クラスを利用して
一度、メモリーDCにBMP展開させてやり、
それをスキャンしてDIBデータ-を取得したいと
思っております。
ところが、いろんな書籍とか、HPをしらべているのですが
このスキャンの方法が判りません。
どなたかご存知の方がいらっしゃれば教えてください。
(やっぱり、最後は[GetDIBits(・・・)]をつかうのですか。
これだとハンドルとか、幅・高さの取得が必要になりますが、[CHtmlView]
からは、これらは取得できなかったのですが・・・)
JPEGやGIFを読みたいということであれば、
OleLoadPictureFile()
を使ってみてはどうでしょうか?
#include <afxctl.h>
CPictureHolder picture;
LPDISPATCH lpdisp;
if (FAILED(::OleLoadPictureFile(COleVariant(szName), &lpdisp)))
エラー処理
picture.SetPictureDispatch((LPPICTUREDISP)lpdisp);
dairygoods様
すばやい回答有難うございます。
さっそく試してみます。
dairygoodさん、有難うございました。
以下の方法で、Jpegなどの画像を
表示、BMPへ変換後のBMPデータ-の取得できました。
OleLoadPictureFile(・・);
ではなく
OleLoadPicture(・・・);
しかMSDNになくて・・・・
(以下のコメントアウトしてある部分はこれから使う部分で、この
プログラムでは、まだ無関係です)
bool CpJpegView::Picture_Read(CListCtrl *s, int nFiles, int iItem)
{
CPictureHolder pp;
LPDISPATCH ld;
CString FileName = s->GetItemText(iItem,2);
SendComment(FileName);
if(FAILED(::OleLoadPictureFile(COleVariant(FileName),&ld)))
{
MessageBox(Error File Open);
return FALSE;
}
pp.SetPictureDispatch((LPPICTUREDISP)ld);
if(pp.GetType() != PICTYPE_BITMAP) return FALSE;
// CRect cr;RECT r;
BITMAP bm;
HBITMAP hbm;
// HDC hDC;
CDC *pDC=GetDC();
// CBitmap cbm;
OLE_HANDLE phandle;
// LPBITMAPINFO bi;
// BITMAPFILEHEADER bfh;
// BITMAPINFOHEADER bih;
// bi=(LPBITMAPINFO)new BYTE[sizeof(BITMAPINFO)];
// pp.m_pPict->get_CurDC(&hDC);
/// カレントDCハンドル取得。
pp.m_pPict->get_Handle(&phandle); /// GDIハンドル取得。
hbm=(HBITMAP)phandle;
/// GDIハンドルをBITMAPハンドルに変換。
GetObject(hbm,sizeof(BITMAP),&bm); /// GDI(BITMAP)Objectを取得。
// GetDIBits(hDC,oBIT,0,100,NULL,bi,DIB_RGB_COLORS);
int iWidth = bm.bmWidth; /// 表示画像の拡大縮尺はこの値で設定。
int iHeight = bm.bmHeight; /// 表示画像の拡大縮尺はこの値で設定。
// Invalidate();
OnDraw(pDC);
/// pDCに表示。
pp.Render( pDC, &CRect(0,0,iWidth,iHeight), &CRect(0,0,0,0));
pp.m_pPict->Release(); ///開放。
return TRUE;
}
どなたか,MFCのダイアログベースでGetDIBitsによるJPEG→BMP化を
作ったことが以前ある方いらっしゃいますか?
『BitBltはPrintOutできますか?』
を参考にされたらいいと思います。
(無駄なコードも含まれていますが・・・)
さっそく,プリントアウトして,勉強してみます
ありがとうございました.
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でも関係なく
終了時にエラーがでます・・・涙