Im using WFA and C#, and im trying to draw an elipse on top of a picturebox containing an image. here is my code but currently its drawing behind of the PB.
private void Form1_Paint(object sender, PaintEventArgs e)
{
PictureBox pb=new PictureBox();
pb.Location=new Point(10,25);
pb.BackgroundImage = Image.FromFile("fire2_clipped_rev_1.png");
pb.Size = Image.FromFile("fire2_clipped_rev_1.png").Size;
Truck.TruckF(pb.Location, pb.CreateGraphics());
pb.Invalidate();
Controls.Add(pb);
}
static Image truckf = Image.FromFile("fire2_clipped_rev_1.png");
public static void TruckF(Point location, Graphics e)
{
Wheels(truckf.Size,location,e);
}
private static void Wheels(Size simage,Point location,Graphics e)
{
e.FillEllipse(Brushes.Black, location.X / 6F, location.Y / 1.43F, 20, 20);
}
You need to change to handle the Load event on your form. Also the PictureBox is a control and you need to draw an image and hand it to the PictureBox to get this to work. Try this:
private PictureBox pb;
private void Truck_Load(object sender, EventArgs e)
{
pb = new PictureBox();
pb.Location = new Point(10, 25);
Image bg = Image.FromFile("fire2_clipped_rev_1.png");
pb.BackgroundImage = bg;
pb.Size = bg.Size;
Bitmap img = new Bitmap(pb.Size.Width, pb.Size.Height);
pb.Image = img;
using (var g = Graphics.FromImage(img))
{
Truck.TruckF(pb.Location, g);
}
Controls.Add(pb);
}
Related
I created in a Window Form 4 PictureBoxes (pictureBox1, pictureBox2, pictureBox3 and pictureBox4). I also created a function to draw a rectangle on a pictureBox like this:
To create the rectangle:
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
var x = e.X;
var y = e.Y;
var width = 10;
var height = 10;
FwRect = new[]
{
new PointF(x, y), new PointF(x, y + height), new PointF(x + width, y + height),
new PointF(x + width, y)
};
FwRectan = new Rectangle((int)x, (int)y, (int)width, (int)height);
Refresh();
}
Then I added this event for each pictureBox:
this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox3.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox4.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
To draw the rectangle:
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
using (var pen = new Pen(Color.Black, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, FwRectan);
}
}
Eventually, if I move the mouse inside the pictureBox1 and draw a rectangle, it also draw a rectangle for each pictureBox. How can I draw a rectangle only on the pictureBox that the mouse is located at?
Thank you very much!
You have 4 PictureBox, so you need 4 Rectangle to draw current mouse movement:
Rectangle[] _rectangle = new Rectangle[4];
then in both common PictureBox_MouseMove and PictureBox_Paint events you need to identify which value to use, index of picturebox. It can be done by using Tag property or by putting all pictureboxes into array so that their index there will match:
PictureBox _control = new PictureBox[] { pictureBox1, pictureBox2, pictureBox3, pictureBox4 };
The event handles will looks like this
void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
var x = e.X;
var y = e.Y;
var width = 10;
var height = 10;
FwRect = new[]
{
new PointF(x, y), new PointF(x, y + height), new PointF(x + width, y + height),
new PointF(x + width, y)
};
var index = _control.IndexOf(sender);
_rectangle[index] = new Rectangle((int)x, (int)y, (int)width, (int)height);
_rectangle[index].Invalidate();
}
void PictureBox_Paint(object sender, PaintEventArgs e)
{
var index = _control.IndexOf(sender);
using (var pen = new Pen(Color.Black, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, _rectangle[index]);
}
}
Edit:
Actually above solution will remember rectangle for each picturebox. Might not be what you want. The simple fix would be to clear other rectangles in mousemove. Though the more proper solution would be to remember sender from mousemove and only paint matching sender in paint.
Here's an example showing how to store the Rectangle in the .Tag property as mentioned by Sinatr in his post. This example also clears the Rectangle when the mouse leaves so you only ever have one Rectangle being drawn in the current PictureBox:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.pictureBox1.MouseMove += this.PictureBox_MouseMove;
this.pictureBox2.MouseMove += this.PictureBox_MouseMove;
this.pictureBox3.MouseMove += this.PictureBox_MouseMove;
this.pictureBox4.MouseMove += this.PictureBox_MouseMove;
this.pictureBox1.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox2.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox3.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox4.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox1.Paint += this.PictureBox_Paint;
this.pictureBox2.Paint += this.PictureBox_Paint;
this.pictureBox3.Paint += this.PictureBox_Paint;
this.pictureBox4.Paint += this.PictureBox_Paint;
}
private int bxWidth = 10;
private int bxHeight = 10;
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pb = (PictureBox)sender;
pb.Tag = new Rectangle(e.X, e.Y, bxWidth, bxHeight);
pb.Invalidate();
}
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
PictureBox pb = (PictureBox)sender;
if (pb.Tag != null && pb.Tag is Rectangle)
{
Rectangle rc = (Rectangle)pb.Tag;
using (var pen = new Pen(Color.Black, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, rc);
}
}
}
private void pictureBox_MouseLeave(object sender, EventArgs e)
{
PictureBox pb = (PictureBox)sender;
pb.Tag = null; // if you want the box to disappear when the mouse leaves?
pb.Invalidate();
}
}
Here's what it looks like running:
I am using Emgucv and Zxing to create a QR Code Scanner And I have created a customer PictureBox to scan QR Code.The webcam is responsible for scanning the QR Code to PictureBox.And I also want to make an animation of a scan in PictureBox.The code works fine but the animation of the red line doesn't show up in the PictureBox when I start to scan QR code.Here's my Code:
Customer picturebox:
public partial class qrCodeViewer : PictureBox
{
int y = 0;
public Timer _timer;
public qrCodeViewer()
{
InitializeComponent();
}
public void _timer_Tick(object sender, EventArgs e)
{
y += 10;
if (y >= 300)
{
y = 0;
}
Invalidate();
}
protected override void OnPaint(PaintEventArgs pe)
{
Graphics g = pe.Graphics;
g.DrawLine(new Pen(Color.Red, 2f), new Point(0, y), new Point(360, y));
base.OnPaint(pe);
}
}
WinForms:
private void readQR_Click(object sender, EventArgs e)
{
qrRealTime._timer = new Timer();
qrRealTime._timer.Start();
qrRealTime._timer.Interval = 50;
qrRealTime._timer.Tick += new EventHandler(qrRealTime._timer_Tick);
openWebCam();
_timer.Start();
_timer.Tick += new EventHandler(TimerEventProcessor);
}
private void TimerEventProcessor(object sender, EventArgs e)
{
Image<Bgr, Byte> frame = new Image<Bgr, Byte>(360, 280);
frame = cap.QueryFrame();
qrRealTime.Image = frame.ToBitmap();
ZXing.IBarcodeReader reader = new ZXing.BarcodeReader();
ZXing.Result result = reader.Decode(frame.ToBitmap());
if (result != null)
{
}
}
My problem is how to show up the animation in PictureBox?
WinForms's image
The call order in the OnPaint method matters.
First call
base.OnPaint(pe);
to draw the beneath image.
Then call the other two lines to draw the red line. Now the code looks like
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Graphics g = pe.Graphics;
g.DrawLine(new Pen(Color.Red, 2f), new Point(0, y), new Point(360, y));
}
Here is my source code. I can't seem to get the bitmap to show the lines drawn on the panel when I move the mouse with the button pressed. Frustrated and looking for someone to help me finish the code so I can complete the app for my 9-yo daughter. Thank you in advance...
namespace TV_PAINT
{
public partial class ALANA_PAINT : Form
{
Graphics g;
Pen p = new Pen(Color.Black, 7);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int m = 0;
Bitmap BP;
public ALANA_PAINT()
{
InitializeComponent();
tb1.Text = p.Width.ToString();
BP = new Bitmap(pnl1.ClientSize.Width, pnl1.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
}
private void closeButton_Click(object sender, EventArgs e)
{
pnl1.Dispose();
p.Dispose();
this.Close();
}
private void clearButton_Click(object sender, EventArgs e)
{
//pnl1.Invalidate();
p.Color = System.Drawing.Color.Black;
p.Width = 7;
tb1.Text = p.Width.ToString();
//pnl1.Invalidate();
}
private void pnl1_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if (e.Button == MouseButtons.Left)
m = 1;
if (e.Button == MouseButtons.Right)
m = 1;
}
private void pnl1_MouseMove(object sender, MouseEventArgs e)
{
if (m == 1)
{
ep = e.Location;
//g = pnl1.CreateGraphics();
Graphics g = Graphics.FromImage(BP);
g.DrawLine(p, sp, ep);
}
sp = ep;
}
private void pnl1_MouseUp(object sender, MouseEventArgs e)
{
m = 0;
}
BP is just a variable in the form. As I can see, it is not displayed anywhere in your form. Why do you need a bitmap for it.
You can do something like this, just get the graphics of your form, and draw using that graphic. https://msdn.microsoft.com/en-us/library/ztxk24yx(v=vs.110).aspx
Noted: you need to do it on PaintEvent of the form, otherwise your drawing will be removed after the next repaint, so you need some variables to store all of your lines, then draw all of them in the paint event.
System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
System.Drawing.Graphics formGraphics;
formGraphics = this.CreateGraphics();
formGraphics.FillRectangle(myBrush, new Rectangle(0, 0, 200, 300));
myBrush.Dispose();
formGraphics.Dispose();
Updated:
If you want to save your change to a bitmap. You can use Form.DrawToBitmap to save your drawing in the form to a bitmap, then call bitmap.Save() to a file in directory.
How to draw image on tabPage overlapping buttons
Black circles(DrawImage on tabPage8_Paint) should be above the buttons:
http://rghost.ru/6sVBl8mkh/image.png
It must be so:
http://rghost.ru/6BgDM77pq/image.png
My code
public SibModem() {
InitializeComponent();
tabPage8.Paint += new PaintEventHandler(tabPage8_Paint);
gettime();
this.SizeChanged += new EventHandler(this.SibModem_Resize);
}
protected void tabPage8_Paint(object sender, PaintEventArgs e) {
GraphicsUnit units = GraphicsUnit.Pixel;
base.OnPaint(e);
Graphics g = e.Graphics;
g.DrawImage(bg, 0, 0);
Rectangle srcRect = new Rectangle(offsetant, 0, w, h);
g.DrawImage(anten, x, y, srcRect, units);
Rectangle ussdwaitRect = new Rectangle(offsetussd, 0, 64, 64);
g.DrawImage(ussdwait, usx, usy, ussdwaitRect, units);
}
You can't draw above nested controls, so you need to draw parts of the image onto those Buttons.
So combine drawing onto the tabpage and drawing onto the buttons you need to adorn!
Here is a simple example using only one image:
A few class level variables:
Point iLoc = Point.Empty;
Image img = null;
List<Button> overlaidButtons = new List<Button>();
Prepare the image, its position and a list of possibly overlaid buttons:
public Form1()
{
InitializeComponent();
string imgN = #"d:\scrape\gears\gear_12x4hand.png";
img = Image.FromFile(imgN);
iLoc = new Point(100, 100);
overlaidButtons.AddRange(new []{button10,button11,button12,button13 });
// each button calls the same paint event
foreach (Button btn in overlaidButtons) btn.Paint += btn_Paint;
}
The common Paint event. We calculate the relative position of the image..
void btn_Paint(object sender, PaintEventArgs e)
{
Button btn = sender as Button;
e.Graphics.DrawImage(img, new Point(iLoc.X - btn.Left, iLoc.Y - btn.Top));
}
Note that if the Buttons are nested deeper you need to adapt the calculation to include all levels of nesting!
The TabPage Paint event:
private void tabPage5_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(img, iLoc);
}
Try BringToFront method, it brings the control to the front of the z-order.
See this reference on MSDN: https://msdn.microsoft.com/en-us/library/system.windows.forms.control.bringtofront(v=vs.110).aspx
I have a pictureBox1 with image inside and when i click on it its drawing points.
Now i added a reset button i called it when i click on it its should clear all the drawings i did on the pictureBox and leavethe image inside without the drawings on it.
I did:
private void button4_Click(object sender, EventArgs e)
{
Graphics graphics;
graphics = pictureBox1.CreateGraphics();
graphics.DrawImage(pictureBox1.Image, 0, 0);
}
So i draw a lot of points on pictureBox1 then click the button and all points are gone but then once i click on the picturebox1 again i see also the new points but also the old points i did before the clearing.
How can i clear the old drawings so it wont show up on the next clicks ?
This is the paint event: Moved the paint event to a new class:
public static void Paint(List<PointF> pb1points, GraphicsPath pb1gp, Point movingPoint, PictureBox pictureBox1, Graphics e)
{
e.Clear(Color.White);
e.DrawImage(pictureBox1.Image, movingPoint);
Pen p;
p = new Pen(Brushes.Green);
foreach (PointF pt in pb1points)
{
e.FillEllipse(Brushes.Red, pt.X, pt.Y, 3f, 3f);
}
using (Pen pp = new Pen(Color.Green, 2f))
{
pp.StartCap = pp.EndCap = LineCap.Round;
pp.LineJoin = LineJoin.Round;
e.DrawPath(pp, pb1gp);
}
}
You can try using Graphics.Clear().
Reference: http://msdn.microsoft.com/en-us/library/system.drawing.graphics.clear(v=vs.110).aspx
setting the Image property to null should work.
picBox.Image = null;
Ii it's not worked ,you might be used the InitialImage property to display your image.
pictBox.InitialImage = null;
Please refer the link:
Clear image on picturebox
This is working:
private void button4_Click(object sender, EventArgs e)
{
Graphics graphics;
graphics = pictureBox1.CreateGraphics();
graphics.DrawImage(pictureBox1.Image, 0, 0);
pb1points = new List<PointF>();
}