1

画像を PictureBox に読み込み、ユーザーがその上に選択用の四角形を描画できるようにするアプリを設計しています。現在、Paint イベントとブール値を使用して、以前に描画した四角形をクリアします (ドラッグ可能な選択ボックスであるため)。

質問:

前の四角形がイメージからクリアされていないため、コードは失敗します。描画される各四角形は透明ですが、前の四角形がクリアされていないため、効果は不透明な四角形になります。これらの長方形をクリアするにはどうすればよいですか?

論理:

saveStateデフォルトは真です。Paint イベントが初めてトリガーされると、通常の画像を含む状態が保存されます。MouseDown イベントがトリガーされると、長方形の開始位置と、長方形が描画されていることを示すブール値を登録します。

MouseMove イベントがトリガーされると、現在の座標に長方形を描画します。saveStateこれが描画されてfalse のときに Paint イベントがトリガーされる (と思う)ため、四角形を描画する前に通常の画像を復元します。

最後に、MouseUp イベントがトリガーされると、saveStateが true に設定されるため、最後の四角形が描画されたグラフィックスの状態が保存され、最初に戻ります。

について読みましControlPaint.DrawReversibleFrameたが、この記事この質問は、画像に描画するために設計されたものではなく、画面またはフォームに直接描画するように設計されているという印象を与えるため、それが必要なものかどうかわかりません。

コード:

public partial class MainWindow : Form
{
    private bool drawingRectangle;
    private int x1, y1, x2, y2;
    private Image currentImage;
    private GraphicsState previousState;
    private bool saveState;

    public MainWindow()
    {
        InitializeComponent();
        this.drawingRectangle = false;
        this.saveState = true;
    }

    private void EditorPictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        this.x1 = e.X;
        this.y1 = e.Y;
        this.drawingRectangle = true;
    }

    private void EditorPictureBox_MouseMove(object sender, MouseEventArgs e)
    {
        if (this.drawingRectangle)
        {
            this.x2 = e.X;
            this.y2 = e.Y;
            Graphics g = Graphics.FromImage(this.currentImage);
            int[] dim = ImageLibrary.CalculateRectangleDimensions(this.x1, this.y1, this.x2, this.y2);
            g.FillRectangle(new SolidBrush(Color.FromArgb(100, 128, 255, 255)), dim[0], dim[1], dim[2], dim[3]);
            this.Refresh();
        }
    }

    private void EditorPictureBox_Paint(object sender, PaintEventArgs e)
    {
        if (this.saveState)
        {
            this.previousState = e.Graphics.Save();
            this.saveState = false;
        }
        else
            e.Graphics.Restore(this.previousState);
    }

    private void EditorPictureBox_MouseUp(object sender, MouseEventArgs e)
    {
        if (this.drawingRectangle)
        {
            this.drawingRectangle = false;
            // When the mouse click is released, save the graphics state
            this.saveState = true; 
        }
    }

    private void LoadImage2Button_Click(object sender, EventArgs e)
    {
        this.currentImage = Image.FromFile("goat2.jpg");
        this.EditorPictureBox.Image = this.currentImage;
    }   
}

これは(静的ライブラリに保存されている)のコードですCalculateRectangleDimensions

public static int[] CalculateRectangleDimensions(int x1, int y1, int x2, int y2)
{
    int[] dimensions = new int[4]; // x1, y1, width, height
    if (x1 <= x2) // Mouse was dragged to the right
    {
        dimensions[0] = x1;
        dimensions[2] = x2 - x1;
    }
    else // Mouse was dragged to the right
    {
        dimensions[0] = x2;
        dimensions[2] = x1 - x2;
    }

    if (y1 <= y2) // Mouse was dragged up
    {
        dimensions[1] = y1;
        dimensions[3] = y2 - y1;
    }
    else // Mouse was dragged down
    {
        dimensions[1] = y2;
        dimensions[3] = y1 - y2;
    }
    return dimensions;
}
4

1 に答える 1

1

Graphics.Save は、呼び出し時にグラフィックスの内容全体を保存するのではなく、平行移動、スケール、変換などの状態情報を保存するだけです。

既に行った描画を元に戻したい場合は、リバーシブル ペイントのように何かを行うか、描画を元に戻したいときに元の画像を再描画する必要があります。

于 2012-07-25T16:51:32.143 に答える