Получить то, что нарисовано на панели в растровое изображение - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть две формы окна в моем приложении.На главной форме я нажимаю кнопку и открываю второе окно с панелью.В этой форме на панели я рисую вещи и читаю их в графическом окне.

Это кодировка моей основной формы.

        Bitmap retBmp;
        FrmDrawing frmDrawing = new FrmDrawing();
        var result = frmDrawing.ShowDialog();

        if (result == DialogResult.OK)
        {
            retBmp = frmDrawing.bmpNew;
            pbDesign.Image = retBmp;
        }

Вот так я рисую на своей второй форме.

public FrmDrawing()
        {
            InitializeComponent();
            g = pnlDraw.CreateGraphics();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            pen = new Pen(Color.Black, 5);
            pen.StartCap = pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
        }

        private void pbRed_Click(object sender, EventArgs e)
        {
            PictureBox p = (PictureBox)sender;
            pen.Color = p.BackColor;
        }

        private void pnlDraw_MouseDown(object sender, MouseEventArgs e)
        {
            moving = true;
            x = e.X;
            y = e.Y;
            pnlDraw.Cursor = Cursors.Cross;
        }

        private void pnlDraw_MouseMove(object sender, MouseEventArgs e)
        {
            if (moving && x!=-1 && y!=-1 )
            {
                g.DrawLine(pen, new Point(x, y), e.Location);
                x = e.X;
                y = e.Y;
            }
        }

        private void pnlDraw_MouseUp(object sender, MouseEventArgs e)
        {
            moving = false;
            x = -1;
            y = -1;
            pnlDraw.Cursor = Cursors.Default;

        }

        private void btnClear_Click(object sender, EventArgs e)
        {

            g.Clear(Color.White);
            pnlDraw.Invalidate();
        }

        private void btnAccept_Click(object sender, EventArgs e)
        {              

            bmpNew = new Bitmap(pnlDraw.Width, pnlDraw.Height);

            this.pnlDraw.DrawToBitmap(bmpNew, new Rectangle(0, 0, this.pnlDraw.Width, this.pnlDraw.Height));
            this.DialogResult = DialogResult.OK;
            this.Close();    
        }

Во второй форме я читаю то, что нарисовано на панели, в BMP и передаю его в формупо нажатию кнопки.Этот код работает почти нормально, за исключением того факта, что он проходит только панель, а не то, что нарисовано на этом.Если на нарисованную панель поместить другие двухцветные элементы управления графическим блоком, отображаемое изображение поставляется с этими цветными графическими блоками, а не с тем, которое я рисую на панели.Что я делаю не так при чтении того, что я нарисовал на панели в растровое изображение?Или что нужно исправить, чтобы получить то, что я рисую на панели, в растровое изображение.

1 Ответ

0 голосов
/ 06 декабря 2018

Прежде всего, как вы можете прочитать на MSDN :

Объект Graphics, который вы получаете с помощью метода CreateGraphics, обычно не следует сохранять послетекущее сообщение Windows было обработано, потому что все, что нарисовано этим объектом, будет удалено со следующим сообщением WM_PAINT.Поэтому вы не можете кэшировать объект Graphics для повторного использования, за исключением использования невизуальных методов, таких как Graphics.MeasureString.Вместо этого вы должны вызывать CreateGraphics каждый раз, когда хотите использовать Graphics объект, а затем вызывать Dispose, когда вы закончите его использовать.

(выделено мной)

Таким образом, вы не должны создавать объект Graphics в конструкторе формы, вы должны динамически создавать и размещать его в обработчике событий.

Но это все равно не поможет.Попробуйте переместить форму за пределы экрана и обратно, и вы заметите, что все ваши пользовательские рисунки исчезают.Это потому, что вы не сохраняете их - они отображаются только один раз.

Вместо использования панели, используйте PictureBox и рисуйте линии непосредственно на Bitmap.

pnlDraw теперь PictureBox, а не Panel:

public FrmDrawing()
{
  InitializeComponent();
  pnlDraw.Image = new Bitmap(pnlDraw.Width, pnlDraw.Height);
}

private void pnlDraw_MouseMove(object sender, MouseEventArgs e)
{
    if (moving && x!=-1 && y!=-1 )
    {
        // Create Graphics object dynamically
        using (var g = Graphics.FromImage(pnlDraw.Image))
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            using (var pen = new Pen(Color.Black, 5))
            {
                pen.StartCap = pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;

                g.DrawLine(pen, new Point(x, y), e.Location);  
            }
        }

        // This is necessary; otherwise, we won't see the changes until
        // the picture box is repainted by the OS
        pnlDraw.Invalidate();

        x = e.X;
        y = e.Y;
    }
}
...