> 180度回転する件ですが、BITMAPINFOHEADER を作成する際
> biHeight の値をマイナス掛けすればうまくいきました。
> ( って、こんな修正でいいのでしょうかとやや不安 )
そんな修正でよかったりします。
biHeight が正の値の場合はボトムアップですが、負の値の場合はトップダウンとなりま
す。
ただし、場合によるとトップダウンビットマップを解釈しないビューワがあるかもしれ
ませんので、より確実を期するならボトムアップがいいでしょう。
biHeight を負にするだけでも、間違いではありません。
なお、biWidth を負にしても左右反転にはなりませんので注意。
いちお~補足ですが…
「上下反転」であって「180度回転」ではないです。
意味が変わりますので注意された方がよろしいかと。
ご返答ありがとうございます。
ゆうさん >
とりあえず、言われたとおり、HBITMAP や hDC 等をメンバ変数にし
ビットマップ作成は画像を読み込んだ時のみ行い
BitBlt() は毎割り込み行う方法でやってみようと思います。
結果はまた報告させていただきます。
シャノンさん、瀬戸っぷさん >
なるほど。少し不安だったので安心しました。
新たな忠告も肝に命じておきます。
ちょっと表題からははずれるのですが、
現在ピクチャボックスを 160 x 136 の大きさで配置しています。
これはダイアログエディタ上のサイズです。
そこに 128 x 128 のビットマップを表示してみたのですが
かなり小さいというか左右などはちょうど半分ぐらいに収まっています。
ダイアログ座標というものを考えても予想以上に小さかったので
ん??と思いました。
このサイズについての違いといいますか、その辺りを少し詳しく
教えていただければと思います。
よろしくお願い致します。
ダイアログ座標での何ポイントがピクセル単位での何ポイントに相当するかは
ダイアログのフォントの大きさに依存しますので、フォントがデカければデカいほど
ダイアログ座標では同じ値でも、ピクセル単位では差が大きくなりますが。
ちなみに、デザイン時にダイアログ座標をいくつにすればピクセル単位で望みの
値になるのかはわかりません。
ご存知でしたらぜひ教えていただけないでしょうか。
ご返答ありがとうございます。
シャノンさん >
なるほど。なんとなく納得しました。
自分なりに色々調整してみようと思います。
ピクチャボックスへの描画の件ですが、例のメンバ変数を用意し
BitBlt() だけ毎割り込み行う方法で、うまくいってるっぽいです。
ありがとうございました。
ここでささいなしつもんなのですが、
HDC とか HBITMAP は最後に DeleteObject なり ReleaseDC を行うと思います。
私の場合は
// ビットマップ作成部分より抜粋
p_pic = (CWnd *)GetDlgItem(IDC_PICTURE);
hDC = p_pic->GetDC()->GetSafeHdc();
hCompatiDC = CreateCompatibleDC(hDC);
myDIB = CreateDIBSection( (HDC)0, (BITMAPINFO *)(&p_tex->m_bi),
DIB_RGB_COLORS, (void **)&pBitsDib, NULL, 0 );
-------------------------------------------------------------------
// 解放部分
DeleteObject( myDIB );
DeleteObject(hCompatiDC);
ReleaseDC(hWnd, hDC);
こういう感じなのですが (かなり省略して書いていますが)
仮にこの hDC, hCompatiDC, myDIB が一度も使われないまま
解放処理(削除処理)を行った場合というのは大丈夫なのでしょうか?
素人丸出しの質問で恐縮ですが
よろしくお願いします。
> ちなみに、デザイン時にダイアログ座標をいくつにすればピクセル単位で望みの
> 値になるのかはわかりません。
> ご存知でしたらぜひ教えていただけないでしょうか。
ピクセル単位で処理したことはありませんが…
とりあえず、下記のページ辺りが参考になるでしょうか?(Delphiのページだったりしますが)
http://homepage2.nifty.com/Mr_XRAY/Halbow/Chap23.html
「ダイアログ単位」ってヤツですね。
変換式が書かれているので参考になるかと。
> こういう感じなのですが (かなり省略して書いていますが)
> 仮にこの hDC, hCompatiDC, myDIB が一度も使われないまま
> 解放処理(削除処理)を行った場合というのは大丈夫なのでしょうか?
作成と解放をドコに記述したかによるのではないでしょうか?
MFCは詳しくないのでドコに書くのが適切なのか判りませんが。
(コンストラクタとデストラクタ? OnInitDialogとOnDestory?)
> 作成と解放をドコに記述したかによるのではないでしょうか?
> MFCは詳しくないのでドコに書くのが適切なのか判りませんが。
> (コンストラクタとデストラクタ? OnInitDialogとOnDestory?)
変数自体は、基本となるビュークラスのメンバとして宣言しています。
で、画像の読み込みが一度でも行われれば使われるといった感じです。
解放は同じビュークラスのデストラクタで行っています。
なので、画像を一度も読み込まずにアプリを終了すれば
一度も使ってはいないけど解放ということになります。
ダイアログ単位について語るスレではないでしょうから、それに関してはこの辺で打ち
止めにして、あとは別スレを立てるなりした方がよいかと。
参考までに、以前この掲示板でダイアログ単位について質問したスレ。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200312/03120064.txt
問題点としては、
・GetDialogBaseUnits で取得した値は、ダイアログのフォントが「System」だと
想定している
・ダイアログのプロパティで「Use System Font」を TRUE にしても、フォントは
「System」ではなく「MS Shell Dlg」になってしまう。
の2点。
で、今やって見た所、わりとすんなりできたので変換関数を掲載。
// フォントを考慮した GetDialogBaseUnits 改良版
void CHogeDlg::GetDialogBaseUnits2( LONG & baseUnitX, LONG & baseUnitY )
{
DWORD dwStyle = GetStyle();
if( ( dwStyle & ( DS_SETFONT | DS_SHELLFONT ) ) == 0 )
{
DWORD dwBaseUnits = GetDialogBaseUnits();
baseUnitX = LOWORD( dwBaseUnits );
baseUnitY = HIWORD( dwBaseUnits );
}
else
{
CDC * pDC = GetDC();
CDC dc;
dc.CreateCompatibleDC( pDC );
CFont * pOldFont = dc.SelectObject( GetFont() );
TEXTMETRIC metric;
dc.GetTextMetrics( &metric );
baseUnitX = metric.tmAveCharWidth;
baseUnitY = metric.tmHeight;
dc.SelectObject( pOldFont );
dc.DeleteDC();
ReleaseDC( pDC );
}
}
// MapDialogRect に相当する関数
void CDLUDlg::DialogUnitToPixel( RECT & rect )
{
LONG baseUnitX = 0;
LONG baseUnitY = 0;
GetDialogBaseUnits2( baseUnitX, baseUnitY );
rect.left = MulDiv( rect.left, baseUnitX, 4 );
rect.top = MulDiv( rect.top, baseUnitY, 8 );
rect.right = MulDiv( rect.right, baseUnitX, 4 );
rect.bottom = MulDiv( rect.bottom, baseUnitY, 8 );
}
// MapDialogRect の逆変換(ピクセル→ダイアログ単位)を行う関数
void CDLUDlg::PixelToDialogUnit( RECT & rect )
{
LONG baseUnitX = 0;
LONG baseUnitY = 0;
GetDialogBaseUnits2( baseUnitX, baseUnitY );
rect.left = MulDiv( rect.left, 4, baseUnitX );
rect.top = MulDiv( rect.top, 8, baseUnitY );
rect.right = MulDiv( rect.right, 4, baseUnitX );
rect.bottom = MulDiv( rect.bottom, 8, baseUnitY );
}
ごめん。この関数じゃうまく行かない場合あり。原因究明中。
表題とかなり内容が変わってきておりますので、一旦解決とし
別スレを立てさせていただこうと思います。
ちなみに、ピクチャボックスのサイズに関しては
以前シャノンさんの立てられたスレにありました
MapDialogRect() を使い、何とかうまくいきそうです。
だらだらと引っ張ってすいませんでした。
ご返答くださった皆様、ありがとうございました。
既に解決してしまっているようですが、一つだけアドバイスを。
ビットマップのラインスキャンの方向を反転するために高さをマイナス値にする
件ですけれど、
仕様上は正しいのですが、ドライバによってはこの辺の解釈が怪しい物もあるようです。
グラフィックボードのドライバ多分大丈夫だと思うのですが、
プリンタドライバに関しては結構手抜きをしている物もあるみたいで
高さをマイナスにするよりも自分で逆にたどるようにした方がトラブルが少ないです。
描画に関してはドライバが絡むので苦労させられます。
特に印刷周りはグラフィックドライバよりも手抜きをしていたり、
独自の実装をしていたりで苦しめられる事が多いのでなるべくプログラム側で
対処してあわせてしまう方が無難です。
半分愚痴ですが、ご参考になれば。