【環境】
Windows7 Home Premium(32bit)
VisualC++ 2010 Express Edition
SDK
【質問】
デスクトップのある範囲をキャプチャするソフトを作っています。
現在は以下のように実装しています。
※hDC, nX, nY, nWidth, nHeightは予め値を格納しています。
HWND hDesktop = GetDesktopWindow();
HDC hDCDesk = GetDC(hDesktop);
RECT Rect;
GetClientRect(hWnd, &Rect);
SetStretchBltMode(hDC, STRETCH_HALFTONE);
StretchBlt(hDC,
0, 0, Rect.right, Rect.bottom,
hDCDesk,
nX, nY, nWidth, nHeight,
SRCCOPY);
ReleaseDC(hDesktop, hDCDesk);
これで動くのですが、拡大縮小がキレイにいきません。SetStretchBltMode()の全てのフ
ラグを試したのですが、キレイになりませんでした。
DrawDIBDraw()を使えば、キレイに拡大縮小できるそうですが、使い方が分からず困って
います。どなたかご教授願います。
DrawDIBDrawに関してはDrawDIBライブラリについて調べて
見てください。google等で調べれば割と色々引っかかるはず。
実際にはVideo for Windowsの中のライブラリとして提供されているようですね。
元々GDIは汎用的な用途を目的に作成されているので
パフォーマンスにしてもクオリティにしてもそこそこの物だと
考えた方が良いと思います。汎用性が高いゆえに便利だけど
細かい所では専用の物に比べて落ちると言うのは仕方がないかなと思います。
どんな画像でも美しく拡大縮小すると言うのは、
実がとても難しい事なのでそれこそそれだけでライブラリができて
しまうくらいだと思います。
フォトレタッチソフト等では、美しさを追求する為に独自のアルゴリズムで
処理しているケースもあると思います。スピードと美しさのトレードオフも
あると思うので結構奥が深い話だと思いますよ。
PATIOさん、お返事ありがとうございます。
>DrawDIBDrawに関してはDrawDIBライブラリについて調べて
>見てください。google等で調べれば割と色々引っかかるはず。
もうちょっと調べてみます。
DrawDIBDraw()のサンプルって少ないですね。動画関連のものが多いみたいです。(>0<;)
>どんな画像でも美しく拡大縮小すると言うのは、
>実がとても難しい事なのでそれこそそれだけでライブラリができて
>しまうくらいだと思います。
>フォトレタッチソフト等では、美しさを追求する為に独自のアルゴリズムで
>処理しているケースもあると思います。スピードと美しさのトレードオフも
>あると思うので結構奥が深い話だと思いますよ。
うーん、実に奥が深そうです。自前で画像の拡大縮小をされている方もいらっしゃるみた
いですね。
ひょっとしたら、簡単な解決法を示してくれる方がいるかもしれないので、とりあえずも
う少しの間、解決済みのフラグを立てないままにしておきます。
GDIとの相互運用でオーバーヘッドが大きくなるかもしれませんが
拡大縮小処理だけGDI+かWICのIWICBitmapScalerに任せてしまうとか。
DrawDIBDrawの品質で問題なさそうならそっちの方が簡単そうですが。
subaruさん、お返事ありがとうございます。
>GDIとの相互運用でオーバーヘッドが大きくなるかもしれませんが
>拡大縮小処理だけGDI+かWICのIWICBitmapScalerに任せてしまうとか。
なるほど調べてみます。
ちなみにまだDrawDIBDraw()がうまく動作しません。(>o<;;)
GDI+で、GraphicsオブジェクトのDrawImageメソッドで描画できることは分かりました。
しかし、DrawImage(DrawImage(Image *srcImage,・・・)は引数がImageであり、この
ImageをhDCからどういうふうに作成していいのかが、分かりません。どなたかお教えくだ
さい。
GDI+は使ったことないですが、
GdiplusGraphics.h や gdiplusheaders.h をのぞいてみた限りでは、
・BitmapクラスはImageクラスを継承している。
(引数でImageクラスを要求する箇所にBitmapクラスを指定できる。)
・Bitmapクラスはコンストラクタで横幅、縦幅、深度を指定して生成できる。
・Graphicsクラスはコンストラクタで、Imageクラスを指定して生成することもできる。
・GraphicsクラスにはHDCを取得できるGetHDC()メソッドがある。
以上のように読み取れました。よって、
・元のHDC(に関連付けられたHBITMAP)と同じ大きさ深度でBitmapオブジェクトを生成し、
・そのBitmapオブジェクトを指定してGraphicsオブジェクトを生成し、
・そのGraphicsオブジェクトのGetHDC()メソッドでHDCを取得して、
・元のHDC→GetHDC()メソッドで得たHDC へBitBltする。
というのはどうでしょうか。
試していないので、あくまで可能性の1つとして。