質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

3回答

5783閲覧

WinForm C# 大量描画速度 DrawImage 遅い

gamu

総合スコア31

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

2クリップ

投稿2018/12/12 14:08

1366721のpictureBox1に15040のサイズでランダムな座標で線を99回描いたものをタイル状に並べて描画します。

trackBar1のScrollイベントによって描画します。
(もしも描画中に追加で描画しようとした時はキャンセル)

それの描画に要した時間をlabel1に表示します。

100msほどかかります。
見た目にはカクカクしています。
これってもうこれ以上速くならないんでしょうか?

描画した時のようす

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } int seed = 10000; bool drawBusy = false; private void drawDemand() { if (drawBusy) return; drawBusy = true; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); draw(pictureBox1); //draw(pictureBox2); sw.Stop(); double time = sw.ElapsedTicks / (double)System.Diagnostics.Stopwatch.Frequency * 1000.0; label1.Text = time.ToString(); label1.Refresh(); drawBusy = false; } private void draw(PictureBox tgtPicBox) { int w = tgtPicBox.Width; int h = tgtPicBox.Height; int miniW = 150; int miniH = 40; Bitmap big = new Bitmap(w, h); Graphics g = Graphics.FromImage(big); for (int y = 0; y < h; y += miniH) { for (int x = 0; x < w; x += miniW) { seed++; g.DrawImage(minibitmapGet(miniW, miniH, seed), x, y, miniW, miniH); } } tgtPicBox.Image = big; tgtPicBox.Refresh(); g.Dispose(); } private Bitmap minibitmapGet(int width, int height,int seed) { Bitmap rslt = new Bitmap(width,height); System.Random r = new System.Random(seed); int[] xRan = new int[100]; for (int i = 0; i < xRan.Length; i++) { xRan[i] = r.Next(width); } int[] yRan = new int[100]; for (int i = 0; i < yRan.Length; i++) { yRan[i] = r.Next(height); } Graphics g = Graphics.FromImage(rslt); //g.DrawLines(Pens.Black, ps); for (int i = 0; i < 99; i++) { g.DrawLine(Pens.Black, xRan[i], yRan[i], xRan[i+1], yRan[i+1]); } g.Dispose(); return rslt; } private void trackBar1_Scroll(object sender, EventArgs e) { drawDemand(); } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/12/13 01:37

これは何のために行うものなんですか? それによって最適なチューニング方法が変わってきます。
gamu

2018/12/13 03:25

大量の異なる形の図形を画面に頻繁に描くためのものです。
Zuishin

2018/12/13 06:32

だとするとループの中を最適化するわけにいかないので方法は限られますし劇的な効果も期待できませんね。 たちまち思いつくのは GDI を使わずもっと高速な描画ライブラリを使うというところくらいでしょうか。 もしそうでなければ場合によっては描画と表示を分離してあらかじめ非同期で描いておいたものを表示することで高速に見せる方法もとれますが。
gamu

2018/12/13 22:35

GDIだけが線を描けるのだと思っていました。 そういったやりかたもあるのですね
guest

回答3

0

アンチエイリアス機能を無効化すればもう少し線の描画速度はあがる気がします。
当然ジャギーは出ますが。

https://dobon.net/vb/dotnet/graphics/antialias.html

見た目の綺麗さより速度を優先するのであれば、こういった手もあります。

投稿2018/12/13 05:15

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gamu

2018/12/13 22:36

回答ありがとうございます。 SmoothingModeをHighSpeedにしました。 無指定の場合と特に歴然とした差はありませんでした
guest

0

ベストアンサー

minibitmapGet内でBitmapを作成し、それを返してDrawImageで描画するのではなく、直接PictureBoxの指定の位置に線を描画する
minibitmapGet内のループを1つにする。
・DrawLinesを使う

この3点でそこそこ変わるかと思います。

投稿2018/12/12 15:08

YAmaGNZ

総合スコア10242

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gamu

2018/12/13 22:39

回答ありがとうございます。 DrawLinesは確かに高速になりました。  しかし現在計画している描画対象には不適なのがつらいところです
YAmaGNZ

2018/12/13 22:47

処理によって高速化の手法は変わってきますので、どのような描画に対してもというのであれば、Zuishinさんのおっしゃるように高速なライブラリを使うのが一番の早道だと思います。
guest

0

new Random はプログラム起動時に1度だけで良い。
minibitmapGetでBitmapを作るのではなく、bigの座標とGraphicsを渡して直接描画する。

投稿2018/12/13 01:33

Q71

総合スコア995

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gamu

2018/12/13 22:37

回答ありがとうございます。 Randomのインスタンスを一度だけにしてみました。 速度に変化ありませんでした。 直接描画してもおなじでした
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問