2016-06-14 6 views
1

Я пытаюсь рисовать круги с помощью растрового изображения.Рисование нового растрового изображения круга в месте щелчка при сохранении ранее нарисованных кругов

Каждый раз, когда я нажимаю на мышь, круг, который я ранее рисовал, перемещается в новое положение.

Я хочу, чтобы это произошло: каждый раз, когда я нажимаю на мышь, новый или новый круг создается в позиции, которую я нажал, и все ранее нарисованные круги остаются без движения.

Я работаю со следующим кодом:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace multirectangle 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
    } 
    Bitmap background; 
    Graphics scG; 

    Rectangle rectangleObj; 

    private Point clickCurrent = Point.Empty; 
    private Point clickPrev = Point.Empty; 


    private void Form1_Load(object sender, EventArgs e) 
    { 
     background = new Bitmap(Width, Height); 
     rectangleObj = new Rectangle(10, 10, 30, 30); 
     scG = Graphics.FromImage(background); 
    } 

    private void Form1_MouseDown(object sender, MouseEventArgs e) 
    { 
     clickCurrent = PointToClient(Cursor.Position); 
     clickPrev = clickCurrent; 
     if (clickPrev == Point.Empty) return; 
     rectangleObj.X = clickPrev.X - rectangleObj.Height/2;// +radius; 
     rectangleObj.Y = clickPrev.Y - rectangleObj.Width/2; 
     Refresh(); 
    } 

    protected override void OnPaint(PaintEventArgs pe) 
    { 
     pe.Graphics.DrawImage(Draw(), 0, 0); 

    } 
    public Bitmap Draw() 
    { 
     Graphics scG = Graphics.FromImage(background); 
     Pen myPen = new Pen(System.Drawing.Color.Red, 3); 
     scG.Clear(SystemColors.Control); 
     scG.DrawEllipse(myPen, rectangleObj); 
     return background; 

    } 
} 
} 
+0

Помните, что программа не знает, чем вы нарисовали последний кадр. Скорее всего, вам нужно будет сохранить список позиций, а затем нарисовать их каждый кадр. –

+0

Этот 'scG.Clear' всегда очищает растровое изображение. Удалите его и отчитайте. Также обратите внимание, что это немного запутанно, мягко говоря. – TaW

ответ

2

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

  1. Не очищайте растровое изображение перед тем, как нарисовать. scG.Clear(SystemColors.Control); очистит растровое изображение, которое вы только что нарисовали. Если вы удалите эту строку и не очистите растровое изображение, то в следующий раз, когда вы нажмете, он затем нарисует новый эллипс прямо поверх последнего растрового изображения.
  2. Если вы хотите получить свежий рисунок/растровое изображение каждый раз, вам понадобится список ваших rectangleObj. Каждый раз, когда вы нажимаете, вы добавляете эту точку в свою коллекцию rectangleObj. Затем в вашем методе рисования вы будете проходить через коллекцию и нарисовать все из них.
+0

Спасибо, что ответили на вопрос, вы правы, мой английский не самый лучший .. и у вас есть то, что мне нужно. Метод не будет отвечать моим потребностям, методу 2 более реалистично, и я подумал об этом. Но потому что я новичок в C#. Я не знаю, как это сделать. Например, я хочу создать список rectangle0bj, чтобы я мог нарисовать 100 кругов .. как можно Я делаю это?? – user6425922

+0

В вашем классе вам нужен элемент, представляющий собой контейнер прямоугольников. Простым примером является список. Добавить: 'Список rectangleList' Затем, когда вы получите свой прямоугольникObj, добавьте его в список:' rectangleList.Add (rectangleObj) '. Теперь в ничьей, вы перебираете список и рисуете каждый. Простой способ: for (int i = 0; i Ryan

+0

Спасибо за полезные комментарии, я решил проблему, используя второй метод. Но теперь я столкнулся с новой проблемой: слишком медленный запуск кода. Посмотрите на http://stackoverflow.com/questions/37843054/который-часть-of-the-code-make-c-sharp-running-too-slowand-it-it-something-fixab – user6425922

1

Я заметил несколько вещей. Во-первыхи, в Form1_MouseDown(), у вас есть это:

clickCurrent = PointToClient(Cursor.Position); 
clickPrev = clickCurrent; 

Вы перезаписаны старая позиция (clickPrev), прежде чем вы даже сохранить его. Если вы хотите сохранить обе позиции, вы должны поместить их в простую структуру, такую ​​как List. Когда вы получите новую точку, просто Add() это к списку. Затем в вашей подпрограмме Draw() переберите все элементы в списке и нарисуйте их все.

Если вы хотите две позиции - и только два - просто поменять свои заявления, как это:

clickPrev = clickCurrent; 
clickCurrent = PointToClient(Cursor.Position); 

И вам придется выделить еще один прямоугольный объект для рисования, хотя было бы сделать больше смысл позаботиться об этом в рутине Draw().

1

своп позиции следующих утверждений

clickCurrent = PointToClient(Cursor.Position); 
clickPrev = clickCurrent; 

Я думаю, вы назначая clickCurrent к clickPrevious после инициализации clickCurrent. Это должно быть наоборот.

1

Пожалуйста, попробуйте этот

Rectangle rectangleObj; 
Bitmap background; 
Graphics scG; 
Pen myPen; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    rectangleObj = new Rectangle(10, 10, 30, 30); 
    background = new Bitmap(Width, Height); 
    scG = Graphics.FromImage(background); 
    myPen = new Pen(Color.Red, 3); 

    BackgroundImage = background; 
} 

private void Form1_MouseDown(object sender, MouseEventArgs e) 
{ 
    var point = PointToClient(Cursor.Position); 

    rectangleObj.X = point.X - rectangleObj.Height/2; 
    rectangleObj.Y = point.Y - rectangleObj.Width/2; 

    scG.DrawEllipse(myPen, rectangleObj); 
    Refresh(); 
} 

OnPaint и Draw методы удалены. Также как clickCurrent и clickPrev полей.

Когда вы меняете размер формы (например, увеличивайте ее), растровые изображения и графика остаются неизменными, поэтому вы получаете этот эффект.Чтобы избежать этого, необходимо добавить обработчик событий

private void Form1_SizeChanged(object sender, EventArgs e) 
{ 
    background = new Bitmap(Width, Height); 
    scG = Graphics.FromImage(background); 
    BackgroundImage = background; 
} 

Обратите внимание, что каждый раз, когда вы изменить размер формы, все ранее отрисовываемый стираются. Если это нежелательно, для рисования необходим другой подход. Дайте мне знать, я приведу еще один пример.

+0

спасибо за попытку, но этот код даст мне несколько кругов, которые можно нарисовать на в то же время и имеют фиксированное расстояние друг от друга. Это полезно, но, к сожалению, не для того, что мне нужно делать. – user6425922

+0

@ user6425922 - Я тебя не понимаю. Код делает именно то, что вы хотели. Я могу предположить, что вы меняете размер формы во время работы, не так ли? –

+0

Это то, что получил http://postimg.org/image/tyepklc1z/ – user6425922

 Смежные вопросы

  • Нет связанных вопросов^_^