In my Form, I have 2 picturebox
controls. I loaded a blue background image on pictureBox1
and left pictureBox2
control alone. With the code below I'm able to draw arrows on top of my picturebox1
image.
Goal: On my pictureBox1_MouseUp
event I want to add all the arrows which I drew on pictureBox1
to pictureBox2
.
Issue: The problem is on my pictureBox1_MouseUp
event when I wrote pictureBox2.Image = pictureBox1.Image
it doesn't add the painted arrow which I drew on pictureBox1. It only adds the pictureBox1 image that I assigned in my form load event.
private bool isMoving = false;
private Point mouseDownPosition = Point.Empty;
private Point mouseMovePosition = Point.Empty;
private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
Pen _Pen;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (isMoving)
{
if (pictureBox1.Image == null) e.Graphics.Clear(Color.White);
// Add this line for high quality drawing:
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
_Pen = new Pen(Color.IndianRed, 3);
_Pen.CustomEndCap = bigArrow;
e.Graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition);
_Pen.Dispose();
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isMoving = true;
mouseDownPosition = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (isMoving)
{
lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition));
}
isMoving = false;
pictureBox2.Image = pictureBox1.Image;
}
Test 1: (Changed pictureBox1_Paint code)
With this code, it draws the arrow on pictureBox2, but it looks like it is drawing multiple arrows.
if (isMoving)
{
if (pictureBox1.Image == null) e.Graphics.Clear(Color.White);
// Add this line for high quality drawing:
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
_Pen = new Pen(Color.IndianRed, 3);
Bitmap BitImg = (Bitmap)pictureBox1.Image;
_Pen.CustomEndCap = bigArrow;
using (var graphics = Graphics.FromImage(BitImg))
{
graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition);
}
pictureBox1.Image = BitImg;
_Pen.Dispose();
}
Test 2: (I took the code from the paint event and pasted it MouseMove Event with some modifications. This uses too much memory and it doesn't draw on pictureBox1 but the arrow is now visible in pictureBox2)
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
if (isMoving)
{
AdjustableArrowCap bigArrow = new AdjustableArrowCap(5, 5);
_Pen = new Pen(Color.IndianRed, 3);
BitImg = new Bitmap(pictureBox1.Image);
_Pen.CustomEndCap = bigArrow;
using (var graphics = Graphics.FromImage(BitImg))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawLine(_Pen, mouseDownPosition, mouseMovePosition);
}
_Pen.Dispose();
}
pictureBox1.Invalidate();
}
}
Draw all lines to pictureBox1:
Draw only last line to pictureBox1:
In
pictureBox2
control, addPaint
event topictureBox2_Paint
.I suggest you make pen and cap global varriable:
In
Form1()
event, add this line:and do as following:
Above code draw lines to PictureBox control, not to image, this allow you remove some lines or clear all lines you draw to picturebox if you want later.
If you want draw directly to image, things event much easier, you don't need
pictureBox2_Paint
at all:You have two problems here:
You paint on Control rather than an image. The image remains unchanged.
Both
pictureBox1
andpictureBox2
refer to the same image. When you change the image, both controls will be affected on the next paint event.So in
pictureBox1_Paint
you need create a copy ofpictureBox1.Image
(try usingBitmap
), then paint on it and assign the updated image topictureBox1.Image
. It will be painted automatically.