i have this code:
Dictionary<int, Class1> MyDict = new Dictionary<int, Class1>();
i get mouse position
private void panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{ Mycl.X1 = e.X;
Mycl.X2 = e.Y;}
private void panel1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Mycl.X3 = e.X;
Mycl.X4 = e.Y;
MyDict.Add(MyDict.Count + 1, Mycl);
panel1.Invalidate();
Mycl = new Class1();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (panel1.BackgroundImage == null)
{
panel1.BackgroundImage = new Bitmap(this.Width, this.Height);
}
Pen MyPen = new Pen(Color.Black);
Graphics G = Graphics.FromImage(panel1.BackgroundImage);
foreach (KeyValuePair<int, Class1> kvp in MyDict)
{
Point pl1 = new Point(MyDict[kvp.Key].X1, MyDict[kvp.Key].X2);
Point pl2 = new Point(MyDict[kvp.Key].X3, MyDict[kvp.Key].X4);
//e.Graphics.DrawLine(MyPen, pl1, pl2);
G.DrawLine(MyPen, pl1, pl2);
}
}
but when I paint this picture, I have a trouble.
When I use e.graphics.drawline() line has drawn
but with G.drawline() there is no line.
In the end, I need to save my picture, but with e.drawline i have a black picture.
Try this out...note the differences and that I also added a MouseMove() handler for panel1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private class Class1
{
public int X1, X2, X3, X4;
}
private Class1 Mycl = new Class1();
private Dictionary<int, Class1> MyDict = new Dictionary<int, Class1>();
private void panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Mycl.X1 = e.X;
Mycl.X2 = e.Y;
Mycl.X3 = e.X;
Mycl.X4 = e.Y;
Point pt1 = panel1.PointToScreen(new Point(Mycl.X1, Mycl.X2));
Point pt2 = panel1.PointToScreen(new Point(Mycl.X3, Mycl.X4));
ControlPaint.DrawReversibleLine(pt1, pt2, panel1.BackColor);
}
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Point pt1 = panel1.PointToScreen(new Point(Mycl.X1, Mycl.X2));
Point pt2 = panel1.PointToScreen(new Point(Mycl.X3, Mycl.X4));
ControlPaint.DrawReversibleLine(pt1, pt2, panel1.BackColor);
Mycl.X3 = e.X;
Mycl.X4 = e.Y;
pt2 = panel1.PointToScreen(new Point(Mycl.X3, Mycl.X4));
ControlPaint.DrawReversibleLine(pt1, pt2, panel1.BackColor);
}
}
private void panel1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Mycl.X3 = e.X;
Mycl.X4 = e.Y;
MyDict.Add(MyDict.Count + 1, Mycl);
panel1.Invalidate();
Mycl = new Class1();
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen MyPen = new Pen(Color.Black))
{
foreach (KeyValuePair<int, Class1> kvp in MyDict)
{
Point pl1 = new Point(kvp.Value.X1, kvp.Value.X2);
Point pl2 = new Point(kvp.Value.X3, kvp.Value.X4);
e.Graphics.DrawLine(MyPen, pl1, pl2);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, new Rectangle(new Point(0,0), panel1.Size));
bmp.Save(#"C:\Users\Mike\Pictures\SomeImage.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
you need to differentiate between your screen graphics and your bitmap objects graphics ...
here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Button button1;
private PictureBox pictureBox1;
private Bitmap bmp;
private Point? p1 = null;
public Form1()
{
InitializeComponent();
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
}
pictureBox1.Image = bmp;
}
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Location = new System.Drawing.Point(0, 23);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(477, 352);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
//
// button1
//
this.button1.Dock = System.Windows.Forms.DockStyle.Top;
this.button1.Location = new System.Drawing.Point(0, 0);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(477, 23);
this.button1.TabIndex = 1;
this.button1.Text = "write bitmap to file";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.ClientSize = new System.Drawing.Size(477, 375);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.button1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "Form1";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
p1 = pictureBox1.PointToClient(MousePosition);
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Point p2 = pictureBox1.PointToClient(MousePosition);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawLine(Pens.Black, p1.Value, pictureBox1.PointToClient(MousePosition));
}
p1 = null;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (p1 != null)
{
e.Graphics.DrawLine(Pens.Black, p1.Value, pictureBox1.PointToClient(MousePosition));
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
pictureBox1.Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
var dialog=new SaveFileDialog();
dialog.DefaultExt = "bmp";
dialog.ValidateNames = true;
dialog.Filter = "Bitmap|*.bmp";
dialog.AddExtension = true;
dialog.OverwritePrompt=true;
var result=dialog.ShowDialog(this);
if (result == System.Windows.Forms.DialogResult.OK)
{
using (var fs = dialog.OpenFile())
{
bmp.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
}
}
}
}
}
in the example you can see 2 different DrawLine(...) calls ... the one in the paint event handles on screen painting, which is NOT persisted in the bitmap ... the one in mouse up handles the modifications in the bitmap ...
Related
I'm doing a school project using C# in which I designed a Form in C# that I can draw on and now I need to copy what I draw into a 9 different Images and save them. So far, I tried using the copy from screen function like that:
Size s = this.Size;
Bitmap memoryImage = new Bitmap(s.Width, s.Height, this.CreateGraphics());
Graphics.FromImage(memoryImage).CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s);
memoryImage.Save(#"C:\Users\omerm\Desktop\projectFinals\ProjectFiles\C-Sharp\Drawing\WinFormsApp1\Digits\1.jpg");
My problem is that the image I get from this code includes parts of my screen that aren't part of my Form. And I also need to copy 9 different images who are fractions of this one instead of just the one and make sure those 9 are around the same shape(squares). does anyone know how to do that?
I'm terrible at explaining this so think that I need to take the original image and cut into 9 like in a tic tac toe board and save each one of them as a different image in the shape of squares instead of the original.
full code:
namespace WinFormsApp1
{
public partial class Form1 : Form
{
Pen Pen = new Pen(Color.Black, 2);
int pX, pY;
Graphics g;
public object MemoryImage { get; private set; }
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
pX = e.X;
pY = e.Y;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Graphics g = pictureBox1.CreateGraphics();
g.DrawLine(Pen, pX, pY, e.X, e.Y);
pX = e.X;
pY = e.Y;
}
}
private void button1_Click(object sender, EventArgs e)
{
Size s = this.Size;
Bitmap memoryImage = new Bitmap(s.Width, s.Height, this.CreateGraphics());
Graphics.FromImage(memoryImage).CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s);
memoryImage.Save(#"C:\Users\omerm\Desktop\projectFinals\ProjectFiles\C-Sharp\Drawing\WinFormsApp1\Digits\1.jpg");
}
private void ChooseColor(object sender, EventArgs e)
{
Pen.Color = ((PictureBox)sender).BackColor;
}
}
}
Tried looking online but what I look for is really specific.
Here's an example of persisting the data in a structure and drawing it in the Paint() event. Additionally, I've demonstrated how to tell the PictureBox to draw itself instead of copying the screen:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private List<Point> curSquiggle;
private List<List<Point>> Squiggles = new List<List<Point>>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
curSquiggle = new List<Point>();
curSquiggle.Add(e.Location);
Squiggles.Add(curSquiggle);
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
curSquiggle.Add(e.Location);
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach(List<Point> squiggle in Squiggles)
{
e.Graphics.DrawLines(Pens.Black, squiggle.ToArray());
}
}
private void button1_Click_1(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.ClientRectangle.Width, pictureBox1.ClientRectangle.Height);
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
// Do something with the bmp, like display it in another form:
Form frm = new Form();
frm.AutoSize = true;
PictureBox pb = new PictureBox();
pb.SizeMode = PictureBoxSizeMode.AutoSize;
pb.Image = bmp;
pb.Location = new Point(0, 0);
frm.Controls.Add(pb);
frm.Show();
}
}
Example run:
Here's a different version of the save code which splits the main picture into 9 pieces:
private void button1_Click_1(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.ClientRectangle.Width, pictureBox1.ClientRectangle.Height);
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
int cols = 3;
int rows = 3;
int cellWidth = bmp.Width / cols;
int cellHeight = bmp.Height / rows;
Rectangle destRect = new Rectangle(0, 0, cellWidth, cellHeight);
List<Bitmap> cells = new List<Bitmap>();
for(int r=0; r<rows; r++)
{
for(int c=0; c<cols; c++)
{
Bitmap cell = new Bitmap(cellWidth, cellHeight);
Rectangle srcRect = new Rectangle(c * cellWidth, r * cellHeight, cellWidth, cellHeight);
using (Graphics g = Graphics.FromImage(cell))
{
g.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel);
}
cells.Add(cell);
}
}
foreach(Bitmap cell in cells)
{
Form frm = new Form();
frm.AutoSize = true;
frm.AutoSizeMode = AutoSizeMode.GrowAndShrink;
PictureBox pb = new PictureBox();
pb.SizeMode = PictureBoxSizeMode.AutoSize;
pb.Image = cell;
pb.Location = new Point(0, 0);
frm.Controls.Add(pb);
frm.Show();
}
}
Splitting into nine pieces:
I've tried many methods including bitmap converting and etc.
Here's my code. Would love it someone will explain to me how to save it and why. Thanks!
public partial class Form1 : Form
{
Graphics G;
Pen myPen = new Pen(Color.Black);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int ctrl = 0;
public Form1()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if(e.Button == MouseButtons.Left)
{
ctrl = 1;
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
ctrl = 0;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(ctrl == 1)
{
ep = e.Location;
G = panel1.CreateGraphics();
G.DrawLine(myPen, sp, ep);
}
sp = ep;
}
private void button1_Click(object sender, EventArgs e)
{
colorDialog1.ShowDialog();
myPen.Color = colorDialog1.Color;
colourBtn.BackColor = colorDialog1.Color;
}
private void clrBtn_Click(object sender, EventArgs e)
{
G.Clear(colorDialog2.Color);
}
private void button1_Click_1(object sender, EventArgs e)
{
colorDialog2.ShowDialog();
panel1.BackColor = colorDialog2.Color;
panel1Colourbtn.BackColor = colorDialog2.Color;
}
private void button1_Click_2(object sender, EventArgs e)
{
SaveFileDialog dlgSave = new SaveFileDialog();
dlgSave.Title = "Save Image";
dlgSave.Filter = "Bitmap Images (*.bmp)|*.bmp|All Files (*.*)|*.*";
if (dlgSave.ShowDialog(this) == DialogResult.OK)
{
using (Bitmap bmp = new Bitmap(panel1.Width, panel1.Height))
{
// how do i save my drawing using savefiledialog?
}
}
}
After you edited your question I suggest to do the following:
create a Bitmap member in your Form with the same dimensions as the panel
create the Graphics G from that bitmap
in your panel1_MouseMove draw on that Graphics (effectivly drawing into the bitmp`
in your panel1_Paint draw that bitmap on the panel and
in your button1_Click_2 save that bitmap:
Code example:
public partial class Form1 : Form
{
Bitmap bmp;
Graphics G;
Pen myPen = new Pen(Color.Black);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int ctrl = 0;
public Form1()
{
InitializeComponent();
// create bitmap
bmp = new Bitmap(panel1.Width, panel1.Height);
// create Graphics
G = Graphics.FromImage(bmp);
G.Clear(Color.Black);
// redraw panel
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
// draw bitmap on panel
if (bmp != null)
e.Grahics.DrawImage(bmp, Point.Empty);
}
// shortened for clarity
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(ctrl == 1)
{
ep = e.Location;
// draw onto graphics -> bmp
G.DrawLine(myPen, sp, ep);
}
sp = ep;
// redraw panel
panel1.Invalidate();
}
private void button1_Click_2(object sender, EventArgs e)
{
SaveFileDialog dlgSave = new SaveFileDialog();
dlgSave.Title = "Save Image";
dlgSave.Filter = "Bitmap Images (*.bmp)|*.bmp|All Files (*.*)|*.*";
if (dlgSave.ShowDialog(this) == DialogResult.OK)
{
bmp.Save(dlgSave.FileName);
}
}
}
Try this:
panel1.DrawToBitmap(bmp, new Rectangle(0, 0, panel1.Width, panel1.Height));
bmp.Save(dlgSave.FileName);
first sorry for my English. I am programming application in windows forms. It is something like Packet Tracer. I have four buttons. When I click on them, they dynamicaly create pictureboxes with picture of Router or Switch,.... Each time I click on the button, new picture box(Switch or Router,...), is created. I can also move with this pictureboxes by mouse.
I need to create a button, which connects selected pictureboxes with line(Cable). This pictureboxes should be selected by click on them. It sholud be able to move with this objects(movable line).
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
PictureBox[] picturebox = new PictureBox[100];
public Form1()
{
InitializeComponent();
}
private void router_Click(object sender, EventArgs e)
{
++a;
picturebox[a] = new PictureBox();
picturebox[a].Name = "picturebox" + a;
picturebox[a].Location = new Point(0 + (a-1) *100,100);
picturebox[a].Size = new Size(70, 70);
picturebox[a].BorderStyle = BorderStyle.None;
picturebox[a].SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(picturebox[a]);
picturebox[a].Image = Image.FromFile(#"D:\\router.jpg");
picturebox[a].Refresh();
picturebox[a].MouseDown += new MouseEventHandler(picMouseDown);
picturebox[a].MouseMove += new MouseEventHandler(picMouseMove);
picturebox[a].MouseUp += new MouseEventHandler(picMouseUp);
}
private void Form1_Load(object sender, EventArgs e)
{
}
int x = 0;
int y = 0;
bool drag = false;
private void picMouseDown(object sender, MouseEventArgs e)
{
// Get original position of cursor on mousedown
x = e.X;
y = e.Y;
drag = true;
}
private void picMouseMove(object sender, MouseEventArgs e)
{
if (drag)
{
PictureBox pb = (PictureBox)sender;
// Get new position of picture
pb.Top += e.Y - y;
pb.Left += e.X - x;
pb.BringToFront();
}
}
private void picMouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
private void switch1_Click(object sender, EventArgs e)
{
++b;
picturebox[b] = new PictureBox();
picturebox[b].Name = "picturebox" + b;
picturebox[b].Location = new Point(0 + (b - 1) * 100, 180);
picturebox[b].Size = new Size(70, 70);
picturebox[b].BorderStyle = BorderStyle.None;
picturebox[b].SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(picturebox[b]);
picturebox[b].Image = Image.FromFile(#"D:\HP ProBook 450\Desktop\Grafika\switch1.png");
picturebox[b].Refresh();
picturebox[b].MouseDown += new MouseEventHandler(picMouseDown);
picturebox[b].MouseMove += new MouseEventHandler(picMouseMove);
picturebox[b].MouseUp += new MouseEventHandler(picMouseUp);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void pc_Click(object sender, EventArgs e)
{
++c;
picturebox[c] = new PictureBox();
picturebox[c].Name = "picturebox" + c;
picturebox[c].Location = new Point(0 + (c - 1) * 100, 260);
picturebox[c].Size = new Size(70, 70);
picturebox[c].BorderStyle = BorderStyle.None;
picturebox[c].SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(picturebox[c]);
picturebox[c].Image = Image.FromFile(#"D:\HP ProBook 450\Desktop\pc.jpg");
picturebox[c].Refresh();
picturebox[c].MouseDown += new MouseEventHandler(picMouseDown);
picturebox[c].MouseMove += new MouseEventHandler(picMouseMove);
picturebox[c].MouseUp += new MouseEventHandler(picMouseUp);
}
private void server_Click(object sender, EventArgs e)
{
++d;
picturebox[d] = new PictureBox();
picturebox[d].Name = "picturebox" + d;
picturebox[d].Location = new Point(0 + (d - 1) * 100, 340);
picturebox[d].Size = new Size(70, 70);
picturebox[d].BorderStyle = BorderStyle.None;
picturebox[d].SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(picturebox[d]);
picturebox[d].Image = Image.FromFile(#"D:\HP ProBook 450\Desktop\server.png");
picturebox[d].Refresh();
picturebox[d].MouseDown += new MouseEventHandler(picMouseDown);
picturebox[d].MouseMove += new MouseEventHandler(picMouseMove);
picturebox[d].MouseUp += new MouseEventHandler(picMouseUp);
}
}
}
THank you for your help.
You need to invalidate the parent when you add a picturebox or when you move a picturebox:
(picMouseMove and 4 times in the click handlers, it would be better to use 1 function)
Invalidate();
This is an example OnPaint, drawing lines between the pictureboxes as they are located in the Controls collection: (your picturebox array seems very weird, you always add controls at index 1, always overwriting the previous entry?! i'd suggest using a List if you need to keep a reference to them)
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var pictureBoxes = Controls.OfType<PictureBox>().ToArray();
if (pictureBoxes.Length > 1)
{
for (int i = 1; i < pictureBoxes.Length; i++)
{
DrawLineBetween(e.Graphics, pictureBoxes[i - 1], pictureBoxes[i]);
}
}
}
This function can be used to draw a line between 2 of your boxes:
private void DrawLineBetween(Graphics g, PictureBox from, PictureBox to)
{
g.DrawLine(Pens.Black,
new Point(from.Left + from.Width / 2, from.Top + from.Height / 2),
new Point(to.Left + to.Width / 2, to.Top + to.Height / 2));
}
----- full sample below -----
I refactored your full example, and added the code above to start you off with a working example:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<PictureBox> pictureboxes = new List<PictureBox>();
public Form1()
{
InitializeComponent();
}
private void AddPictureBox(string imagePath)
{
var pb = new PictureBox();
pb.Name = "picturebox" + pictureboxes.Count;
pb.Location = new Point(pictureboxes.Count * 100, 100);
pb.Size = new Size(70, 70);
pb.BorderStyle = BorderStyle.None;
pb.SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(pb);
pb.Image = Image.FromFile(imagePath);
pb.Refresh();
pb.MouseDown += new MouseEventHandler(picMouseDown);
pb.MouseMove += new MouseEventHandler(picMouseMove);
pb.MouseUp += new MouseEventHandler(picMouseUp);
pictureboxes.Add(pb);
Invalidate();
}
private void router_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\\router.jpg");
}
private void Form1_Load(object sender, EventArgs e)
{
}
int x = 0;
int y = 0;
bool drag = false;
private void picMouseDown(object sender, MouseEventArgs e)
{
// Get original position of cursor on mousedown
x = e.X;
y = e.Y;
drag = true;
}
private void picMouseMove(object sender, MouseEventArgs e)
{
if (drag)
{
PictureBox pb = (PictureBox)sender;
// Get new position of picture
pb.Top += e.Y - y;
pb.Left += e.X - x;
pb.BringToFront();
Invalidate();
}
}
private void picMouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
private void switch1_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\Grafika\switch1.png");
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void pc_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\pc.jpg");
}
private void server_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\server.png");
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (pictureboxes.Count > 1)
{
var arr = pictureboxes.ToArray();
for (int i = 1; i < arr.Length; i++)
{
DrawLineBetween(e.Graphics, arr[i - 1], arr[i]);
}
}
}
private void DrawLineBetween(Graphics g, PictureBox from, PictureBox to)
{
g.DrawLine(Pens.Black,
new Point(from.Left + from.Width / 2, from.Top + from.Height / 2),
new Point(to.Left + to.Width / 2, to.Top + to.Height / 2));
}
}
}
i want print the content of panel with RadPrintPreview of telerik , but when i declare RadPrintDocument i cant associat this later with panel !
this is my code :
private void doc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Bitmap bmp = new Bitmap(radPanel2.Width, radPanel2.Height, radPanel2.CreateGraphics());
radPanel2.DrawToBitmap(bmp, new Rectangle(0, 0, radPanel2.Width, radPanel2.Height));
RectangleF bounds = e.PageSettings.PrintableArea;
e.Graphics.DrawImage(bmp, bounds.Left, bounds.Top, radPanel2.Width, radPanel2.Height);
}
private void btn_Imression_Click(object sender, EventArgs e)
{
System.Drawing.Printing.PrintDocument doc = new System.Drawing.Printing.PrintDocument();
doc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(doc_PrintPage);
RadPrintPreviewDialog PrintSettings = new RadPrintPreviewDialog();
PrintSettings.Document = doc;
PageSettings pgsetting = new PageSettings();
if (PrintSettings.ShowDialog() == DialogResult.OK)
doc.Print();
}
and thank's for help :)
In order to print Telerik UI for WinForms control, you should use the embedded in the framework functionality, namely RadPrintDocument, which allows you to print any object implementing the IPrintable interface. Here is how this can be done for RadPanel:
RadPanel panel = new RadPanel();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
InitializeComponent();
panel.Dock = DockStyle.Fill;
panel.BackColor = Color.Red;
panel.Parent = this;
RadButton b = new RadButton();
b.Text = "button1";
panel.Controls.Add(b);
RadButton b2 = new RadButton();
b2.Text = "button1";
b2.Location = new Point(400, 400);
panel.Controls.Add(b2);
}
private class PanelPrinter : IPrintable
{
private RadPanel panel;
public PanelPrinter(RadPanel panel)
{
this.panel = panel;
}
public int BeginPrint(RadPrintDocument sender, PrintEventArgs args)
{
return 1;
}
public bool EndPrint(RadPrintDocument sender, PrintEventArgs args)
{
return false;
}
public Form GetSettingsDialog(RadPrintDocument document)
{
return null;
}
public bool PrintPage(int pageNumber, RadPrintDocument sender, PrintPageEventArgs args)
{
float scale = Math.Min((float)args.MarginBounds.Width / panel.Size.Width, (float)args.MarginBounds.Height / panel.Size.Height);
Bitmap panelBmp = new Bitmap(this.panel.Width, this.panel.Height);
this.panel.DrawToBitmap(panelBmp, this.panel.Bounds);
Matrix saveMatrix = args.Graphics.Transform;
args.Graphics.ScaleTransform(scale, scale);
args.Graphics.DrawImage(panelBmp, args.MarginBounds.Location);
args.Graphics.Transform = saveMatrix;
return false;
}
}
private void radButton1_Click(object sender, EventArgs e)
{
RadPrintDocument document = new RadPrintDocument();
document.AssociatedObject = new PanelPrinter(this.panel);
RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(document);
dialog.ShowDialog();
}
I'm trying to make a simple application where the user can draw on the Panel and save it to their computer as a bitmap. When I proceed to the save part, however, all I get is an empty (white) bitmap.
I've been browsing many other solutions and I am pretty sure I am saving the bitmap the correct way, so I am starting to wonder if my drawing process is incorrect. What exactly is wrong here?
public partial class Form1 : Form
{
SolidBrush brush;
Pen pen;
Point[] points = new Point[3];
Graphics display;
Bitmap bmap;
public Form1()
{
InitializeComponent();
display = panel1.CreateGraphics();
bmap = new Bitmap(panel1.Width, panel1.Height);
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
brush = new SolidBrush(Color.Black);
pen = new Pen(Color.Black);
display.FillEllipse(brush, e.X, e.Y, 10, 10);
panel1.DrawToBitmap(bmap, new Rectangle(0, 0, panel1.Width, panel1.Height));
//this.Invalidate();
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
Graphics display = panel1.CreateGraphics();
display.Clear(panel1.BackColor);
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
bmap.Save(#"C:\Temp\Test.bmp");
}
}
EDIT
With this revision, I just get a black bmp and I don't even see elipses being created anymore on my screen. Although I did notice that if I put invalidate and Draw to bitmap back in the mousedown event, then the save button will save the last ellipse, while there is still nothing appearing on my screen.
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
mousedown = true;
x = e.X;
y = e.Y;
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
//Graphics g = e.Graphics;
if(mousedown==true)
{
brush = new SolidBrush(Color.Black);
pen = new Pen(Color.Black);
Graphics.FromImage(bmap).FillEllipse(brush, x, y, 10, 10);
panel1.Invalidate();
//panel1.DrawToBitmap(bmap, new Rectangle(0, 0, panel1.Width, panel1.Height));
//panel1.Invalidate();
}
}
As Hans did most of the work in his comment, here is how your code should probably look:
public partial class Form1 : Form {
Bitmap bmap;
public Form1() {
InitializeComponent();
bmap = new Bitmap(panel1.ClientWidth, panel1.ClientHeight);
panel1.MouseDown += panel1_MouseDown;
panel1.Paint += panel1_Paint;
}
void panel1_Paint(object sender, PaintEventArgs e) {
e.Graphics.DrawImage(bmap, Point.Empty);
}
void panel1_MouseDown(object sender, MouseEventArgs e) {
using (Graphics g = Graphics.FromImage(bmap)) {
g.FillEllipse(Brushes.Black, e.X, e.Y, 10, 10);
}
panel1.Invalidate();
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e) {
using (Graphics g = Graphics.FromImage(bmap)) {
g.Clear(Color.White);
}
panel1.Invalidate();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e) {
bmap.Save(#"c:\temp\bmap.bmp");
}
}
CreateGraphics is just a temporary canvas, so you rarely, if ever, use that for drawing purposes, especially since you are trying to save an image.
This will works fine. I tested it and worked well
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace drawing
{
public partial class Form2 : Form
{
Graphics g;
bool startPaint = false;
int? initX = null;
int? initY = null;
bool drawSquare = false;
bool drawRectangle = false;
bool drawCircle = false;
public Form2()
{
InitializeComponent();
bmp = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height);
}
Bitmap bmp;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (startPaint)
{
using ( g = Graphics.FromImage(bmp))
{
// g.FillEllipse(Brushes.Black, new Rectangle(e.X, e.Y , 5, 5));
Pen p = new Pen(btn_PenColor.BackColor, float.Parse(cmb_PenSize.Text));
g.DrawLine(p, new Point(initX ?? e.X, initY ?? e.Y), new Point(e.X, e.Y));
initX = e.X;
initY = e.Y;
//g.DrawImage(bmp, new Rectangle(e.X - 4, e.Y - 4, 8, 8));
}
panel1.Invalidate();
}
}
private void pnl_Draw_MouseDown(object sender, MouseEventArgs e)
{
startPaint = true;
if (drawSquare)
{
//Use Solid Brush for filling the graphic shapes
SolidBrush sb = new SolidBrush(btn_PenColor.BackColor);
//setting the width and height same for creating square.
//Getting the width and Heigt value from Textbox(txt_ShapeSize)
g.FillRectangle(sb, e.X, e.Y, int.Parse(txt_ShapeSize.Text), int.Parse(txt_ShapeSize.Text));
//setting startPaint and drawSquare value to false for creating one graphic on one click.
startPaint = false;
drawSquare = false;
}
if (drawRectangle)
{
SolidBrush sb = new SolidBrush(btn_PenColor.BackColor);
//setting the width twice of the height
g.FillRectangle(sb, e.X, e.Y, 2 * int.Parse(txt_ShapeSize.Text), int.Parse(txt_ShapeSize.Text));
startPaint = false;
drawRectangle = false;
}
if (drawCircle)
{
SolidBrush sb = new SolidBrush(btn_PenColor.BackColor);
g.FillEllipse(sb, e.X, e.Y, int.Parse(txt_ShapeSize.Text), int.Parse(txt_ShapeSize.Text));
startPaint = false;
drawCircle = false;
}
}
private void pnl_Draw_MouseUp(object sender, MouseEventArgs e)
{
startPaint = false;
initX = null;
initY = null;
}
void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(bmp, Point.Empty);
}
private void button1_Click(object sender, EventArgs e)
{
bmp.Save("D://filename.jpg", ImageFormat.Png);
}
}
}