DrawImage Image関数を使用して、画像から別の画像に一部をコピーします。コピーした部分を「暗く」することはできますか?特別な色調?誰かが私に例を教えてもらえますか?ImageAttributesと呼ばれるものを聞いたのですが、見つかりません!
注:ソース画像を編集したくありません。
DrawImage Image関数を使用して、画像から別の画像に一部をコピーします。コピーした部分を「暗く」することはできますか?特別な色調?誰かが私に例を教えてもらえますか?ImageAttributesと呼ばれるものを聞いたのですが、見つかりません!
注:ソース画像を編集したくありません。
(必ずしもこの質問への直接の回答ではありませんが
ImageAttributes
、DrawImage
メソッドに指定するとパフォーマンスが低下するというフォローアップの質問への回答です。その質問は削除されましたが、すでに書いているので、とにかくここに回答を投稿しました。無視します。ご希望の場合。)
グラフィックの描画は、特にレンダリング効果を同時に適用している場合は遅くなります。Photoshopで数分間作業すると、私が何を意味するのかがわかります。画像を暗くすることは、計算コストのかかる作業です。それをより速くするためにあなたができることはほとんどありません。
System.Drawing.Graphics
この問題は、.NET Frameworkのクラスのルーチンが、GDI+を使用して内部的に実装されているという事実によってさらに複雑になっています。ハードウェアアクセラレーション。考えられる代替案は、ほとんどのシステムでハードウェアアクセラレーションが行われるGDIベースのレンダリングに戻すことです(ビデオカードのベンダーによって異なりますが、現在のほとんどすべてのカードには、ビットブロック転送などの基本機能のハードウェアアクセラレーションがあります) 。もちろん、GDIベースの描画ルーチンを使用するには、WindowsAPIから関数をP/呼び出しする必要があるため、これははるかに困難です。.NETが提供するのはGDI+だけです。これは必要以上に手間がかかり、最新のハードウェアでは速度の向上はおそらく最小限です(特に、Windows Vista / 7のAeroテーマが有効になっている場合、すべてがメモリ内のビットマップに描画されるため、GDIでもハードウェアアクセラレーションを使用しません) 。
現在の実装に固執すると、いくつかの可能な最適化がまだ頭に浮かびます。
再描画するときに画像のサイズを変更していますか?もしそうなら、それは画像を補間する必要があり、それは比較すると非常に遅いです。
PixelFormat
の画像は何ですか?Format32bppPArgb
代替案よりもはるかに高速です。その形式の画像で作業していることを確認してください。今ではない場合は、この変更を行うと、レンダリング速度が大幅に向上するはずです。
なぜそんなに頻繁に画像を再レンダリングする必要があるのですか?同じ画像の場合は、効果を適用して一度描画し、Bitmap
返されたオブジェクトをキャッシュします。その後、画像を再描画する必要があるたびに、新しい画像を作成するのではなく、すでにメモリにある画像を使用します。これは簡単なトリックですが、毎回高価な部分をやり直す必要がなくなります。おっしゃるように、DrawImage
レンダリングされた属性を設定するよりも、単独の方がはるかに高速です。
一般的に、ユーザーは大きな画像がレンダリングされるのを喜んで待ちます。グラフィックルーチンを最適化しようとするよりも、それに応じてインターフェイスを設定する方が適切です。プログレスバーとビジーカーソルを使用して、実際に何かが起こっていることを示すことは、コードからさらに数ミリ秒を絞り出すよりも、ユーザーに関する限り、はるかに進んでいきます。この効果をループで100回または1000回繰り返し適用しない限り(これはかなりばかげているように見えます)、最適化にかかる時間の価値はありません。
DrawImage関数には、その理由でImageAttributesオブジェクトを正確に設定する特別なオーバーロードもあります。
private void Example(PaintEventArgs e)
{
ImageAttributes imageAttr = new ImageAttributes();
imageAttr.SetGamma(2.2f);
Rectangle rect = new Rectangle(250, 20, 200, 200);
e.Graphics.DrawImage(myImage, rect, 0, 0, 200, 200, GraphicsUnit.Pixel, imageAttr);
}