0

シリアルポートから取得したデータに基づいてゲージを回転させようとしています。シリアル通信はうまく機能していて、ゲージを回転させるのに問題があります。スライダーバーで画像を回転させようとしていますが、まだ運がありません。現在、100ミリ秒ごとにトリガーしてこのコードを実行するタイマーを実装しています。ただし、sliderBarを移動しても、画面上の画像には何も起こりません。私がタイマーを使用している理由は、それが私の最終的な実装に使用するものだからです。Serialイベントの代わりにタイマーを使用してUI更新をトリガーすると、アプリケーションの実行がはるかにスムーズになります。

いつものようにどんな助けでも大歓迎です!

コンストラクターで...

 public Form1()
    {
        InitializeComponent();
        System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
        imgpic = (Image)pictureBoxBase.Image.Clone(); // This is storing an image in a picture box...
        foreach (int rate in baudRates)
        {
            brbox.Items.Add(rate);
        }
        timer.Tick += new EventHandler(timer_Tick);
        timer.Interval = 100;
        timer.Enabled = true;
        timer.Start();

        com.DataReceived += new SerialDataReceivedEventHandler(OnReceived);
    }

次に、タイマーイベントで...

   void timer_Tick(object sender, EventArgs e) // Again it is initially drawing the picture, but it does not rotate with the statusBar
    {

        Point test = new Point(0, 0);
        Image img = new Bitmap(400, 400); 
        pictureBox1.Image = img;
        Graphics g = Graphics.FromImage(pictureBox1.Image);
        Matrix mm1 = new Matrix();
        mm1.RotateAt((trackBar1.Value),new Point( 0,0),MatrixOrder.Append);
        GraphicsPath gp = new GraphicsPath();
        gp.Transform(mm1);
        gp.AddPolygon(new Point[] { new Point(0, 0), new Point(imgpic.Width, 0), new Point(0, imgpic.Height) });
        PointF[] pts = gp.PathPoints;
        g.DrawImage(imgpic, test);
        pictureBox1.Refresh();

    }
4

1 に答える 1

2

主な問題は次のとおりです。

  • 実際に作成したパスを描画しない

  • パスに追加したポリゴンを回転させない (追加後にトランスフォームを適用する必要があります)

ここでメモリ リークが発生する可能性がたくさんあります。管理されていないコンポーネント (ここでは Graphics、GraphicsPath、Image、および Matrix オブジェクト) を持つオブジェクトは、基になる Windows オブジェクトを適切に削除できるように破棄する必要があります (.NET ではこれを実行できません)。

修正コード:

void timer_Tick(object sender, EventArgs e)
{
    if (pictureBox1.Image != null)
        pictureBox1.Image.Dispose(); // dispose old image (you might consider reusing it rather than making a new one each frame)

    Point test = new Point(0, 0);
    Image img = new Bitmap(400, 400); 
    pictureBox1.Image = img;
    Graphics g = Graphics.FromImage(pictureBox1.Image);

    Matrix mm1 = new Matrix();
    mm1.RotateAt((trackBar1.Value), new Point( 0,0), MatrixOrder.Append); // note that the angle is in degrees, so make sure the trackbar value or input is suitably scaled

    GraphicsPath gp = new GraphicsPath();
    gp.AddPolygon(new Point[] { new Point(0, 0), new Point(imgpic.Width, 0), new Point(0, imgpic.Height) });
    //PointF[] pts = gp.PathPoints; // not needed for this task

    g.DrawPath(Pens.Black, gp); // draw the path with a simple black pen
    g.Transform = mm1; // transform the graphics object so the image is rotated
    g.DrawImage(imgpic, test); // if the image needs to be behind the path, draw it beforehand

    mm1.Dispose();
    gp.Dispose();
    g.Disose(); // prevent possible memory leaks
    pictureBox1.Refresh();
}

まだ問題がある場合は、ここにコメントしてください。必要に応じて変更します。

(編集:私がまったく期待していなかった処分するものがたくさんあるようです)

于 2013-01-04T21:25:33.957 に答える