■動作/開発環境
・OS:WinXP Pro
・開発環境:VC++ .NET 2008 MFC
■質問
画像(主にビットマップ)を任意の角度で回転させて表示する
プログラムを作っています。
CDC::PlgBlt で回転をさせているのですが、
イメージのサイズが大体 4000x4000位のモノだと
メソッド自体の戻り値は正常(TRUE)を返すのですが、描画されません。
因みに、角度0度(回転させないでPlgBltを呼ぶ)でも描画されません。
コードは、
CBitmap sBitmap;
BOOL bState = pdc->PlgBlt( point, pMemDC, nX, nY, nW, nH, sBitmap, 0, 0 );
nX, nY については、pMemDCの外を指してる時もあります。(つまりはみ出た場所)
nW, nH については、pMemDCの外を指してる時もあります。(つまりはみ出た場所)
色々調べましたが、原因が分かりません。
原因又は、解決出来る方法をご存知の方がいましたら、
是非、ご教授下さい。
宜しくお願い致します。
CBitmap sBitmap; の実体は DDB ですか、DIB ですか、DIBSection ですか?
通常のデバイスドライバー(プリンターでもグラフイックカードなどでも)では
巨大な DDB が取扱えないものが多いです
DIBSection を使うのが良いでしょう(過去ログを調べてみてください)
MSDNライブラリでPlgBltのリファレンスを見ると、回転や傾斜はできません、とはっき
り書いてあります。
あちらこちらでPlgBltで回転できると紹介されているのですが、保証されている動作な
のでしょうか。
しまさん、ISLeさん、ありがとうございます。
●.しまさん
コード中の「CBitmap sBitmap」は、宣言したものをそのまま引数に
使用しています。(CBitmapのデフォルトコンストラクタでは、モノクロ
ビットマップですので)
やはり、ハードウェアに依存してしまうようですか、残念です。
巨大イメージを扱うには DIBSection 。早速調べてみます。
●.ISLeさん
確かにヘルプには書いてあります。
ですが、実際に出来ます。(私はそれで回転させています)
要は、PlgBltに渡す引数、POINT[3] に回転させた座標値を
入れれば良いです。(sin、cosで計算して。私は数学苦手なので
「やだなぁ」と思いつつやりました。)
結論として、
GDI系APIは、ハード(グラフィックドライバなど)に依存してしまう。
と言う事ですね。
CreateCompatibleBitmapで大きなサイズを指定するとエラーになるのも
その一環という事ですね。(泣)
巨大イメージを扱う場合は、分割して表示などの工夫が必要なのでしょうね。
ありがとうございました。
sin cosの回転座標の計算ができるのですから
出力画像の各ピクセルが入力画像のどのピクセルになるか
も簡単に求められると思います。
出力の各ピクセルの回転前の画素位置計算してコピーすれば
もっとも簡単な回転処理を自前でつくれます。
ただ、これだと直線がガタガタになるのでバイキュービック法
などの補間を入れます。
あとはできた画像をbitbltで表示するだけです。
結構お手軽につくれます。
少々面倒ですが
分割して回転させて、くっつけてはだめですか?
三角関数が使えたらどこの座標に回転されるのかは簡単に求まります。
多少境界が綺麗にならないと思いますので、
オーバラップするようにして、補間してやると綺麗になると思います。