I have a picture and a line in a PictureBox control. I know how to zoom the picture itself using this code :
private void pictureBox1_Click(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (Globals.x == 1)
{
Globals.y = 1;
Globals.a = e.X;
Globals.b = e.Y;
}
}
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Create a local version of the graphics object for the PictureBox.
Graphics g = e.Graphics;
if (Globals.y == 0)
{
e.Graphics.DrawImage(bitmap, 0, 0, 470, 353);
e.Graphics.DrawLine(System.Drawing.Pens.Red, 210, 66, 112, 122);
e.Graphics.DrawLine(System.Drawing.Pens.Red, 112, 122, 15, 205);
}
Bitmap bmpZoom = new Bitmap(bitmap.Width, bitmap.Height);
int new4W = bitmap.Width / 3;
int new4H = bitmap.Height / 3;
int new2W = bitmap.Width *2/ 3;
int new2H = bitmap.Height *2/ 3;
Rectangle srcRect = new Rectangle(Globals.a - new4W,Globals.b - new4H, new2W, new2H);
Rectangle dstRect = new Rectangle(60, 10, bmpZoom.Width, bmpZoom.Height);
}
My code can zoom the part of the picture that i have clicked on, but when I try to draw the line again, it's in the same location anymore (and that is normal).
I want a solution that can zoom both the picture and the line. If anyone could help me, I would be glad.
Related
I was wondering if it's possible to fill a certain percentage of a Rectangle object that's been draw on-screen so that it behaves like a Progress Bar, where you can watch its "level" go up and down. Specifically, I'd like to fill it from top to bottom rather than left to right.
You can try this.
private void button1_Click(object sender, EventArgs e)
{
panel1.Width = 400;
panel1.Height = 50;
using (Graphics g = this.panel1.CreateGraphics())
{
g.Clear(Color.Black);
Pen pen = new Pen(Color.Red, 2);
for (int i = 0; i <= 50;i++ )
{
g.DrawRectangle(pen, 0, 0, 400, i);
Thread.Sleep(100);
}
pen.Dispose();
}
}
have made something to draw on the screen(as overlay for everyting else) but when I move something over the drawing it starts flickering, I have already set DoubleBuffered on true
is their a way to fix this with a dll,function,rendering?
private void button2_Click(object sender, EventArgs e)
{
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Point midx = new Point(960, 960);
Point midy = new Point(540, 540);
Point LinksBoven = new Point(10, 10);
Point pt = Cursor.Position;
string letter = "drawing on";
float emSize = 12;
while (true)
{
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
System.Drawing.Pen myPen;
myPen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0, 200, 0));
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
if (cbCircel.Checked == true)
{
g.DrawEllipse(Pens.Black, midx.X - 10, midy.Y - 10, 20, 20);
}
if (cbKruis.Checked == true)
{
g.DrawLine(myPen, 940, 540, 980, 540);
g.DrawLine(myPen, 960, 560, 960, 520);
}
pt.X = 10;
pt.Y = 10;
g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular), new SolidBrush(Color.Green), pt);
}
}
}
I'm using WinForms. In my form i have a picturebox that contains an image. I provided my code which highlights images by right-clicking and dragging the mouse.
How do I print the image and what i highlighted in the picturebox?
private Random _rnd = new Random();
private Point _pt;
private Point _pt2;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
//set the upper left point of our selection rectangle
if (e.Button == MouseButtons.Left)
_pt = e.Location;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
//display the selected part when mouse button gets released
if (e.Button == MouseButtons.Left)
{
GenerateBmp();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//if we have a valid rectangle, draw it
if (_pt.X - _pt2.X != 0 && _pt.Y - _pt2.Y != 0)
{
//fill
using (SolidBrush sb = new SolidBrush(Color.FromArgb(95, 255, 255, 0)))
e.Graphics.FillRectangle(sb, new Rectangle(_pt.X, _pt.Y, _pt2.X - _pt.X, _pt2.Y - _pt.Y));
//draw
e.Graphics.DrawRectangle(Pens.Blue, new Rectangle(_pt.X, _pt.Y, _pt2.X - _pt.X, _pt2.Y - _pt.Y));
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//set the bottom right one
if (e.Button == MouseButtons.Left)
{
_pt2 = e.Location;
this.pictureBox1.Invalidate();
}
}
private void GenerateBmp()
{
//check, if we have a valid rectangle
if (_pt2.X - _pt.X > 0 && _pt2.Y - _pt.Y > 0)
{
//create that rectangle
Rectangle r = new Rectangle(_pt.X, _pt.Y, _pt2.X - _pt.X, _pt2.Y - _pt.Y);
//create a new Bitmap with the size of the selection-rectangle
Bitmap bmp = new Bitmap(r.Width, r.Height);
//draw the selectex part of the original image
using (Graphics g = Graphics.FromImage(bmp))
g.DrawImage(this.pictureBox1.Image, new Rectangle(0, 0, r.Width, r.Height), r, GraphicsUnit.Pixel);
}
}
private Bitmap SetUpPictures(PictureBox pb)
{
//create a bitmap to display
Bitmap bmp1 = new Bitmap(pb.ClientSize.Width, pb.ClientSize.Height);
//get the graphics-context
using (Graphics g = Graphics.FromImage(bmp1))
{
//get a random, opaque, color
Color c = Color.FromArgb(255, _rnd.Next(256), _rnd.Next(256), _rnd.Next(256));
g.Clear(c);
//better smoothinmode for round shapes
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//draw ten shapes to the bitmap
for (int i = 0; i < 10; i++)
{
//loaction and size rectangle
Rectangle r = new Rectangle(_rnd.Next(pb.ClientSize.Width / 2), _rnd.Next(pb.ClientSize.Height / 2),
_rnd.Next(pb.ClientSize.Width / 2), _rnd.Next(pb.ClientSize.Height / 2));
//random color
Color c2 = Color.FromArgb(_rnd.Next(256), _rnd.Next(256), _rnd.Next(256), _rnd.Next(256));
//one color brush
using (SolidBrush sb = new SolidBrush(c2))
{
//check, if i is odd or even and decide on that to draw rectangles or ellipses
if ((i & 0x01) == 1)
g.FillEllipse(sb, r);
else
g.FillRectangle(sb, r);
}
}
}
//return our artwork
return bmp1;
}
private void Btn_Print_Click(object sender, EventArgs e)
{
System.Drawing.Printing.PrintDocument myPrintDocument1 = new System.Drawing.Printing.PrintDocument();
PrintDialog myPrinDialog1 = new PrintDialog();
myPrintDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(DVPrintDocument_PrintPage);
myPrinDialog1.Document = myPrintDocument1;
if (myPrinDialog1.ShowDialog() == DialogResult.OK)
{
myPrintDocument1.Print();
}
}
private void DVPrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(pictureBox1.Image, 25, 25, 800, 1050);
var rc = new RectangleF(0, 0, pictureBox1.Image.Width / 100f, pictureBox1.Image.Height / 100f);
e.Graphics.DrawImage(pictureBox1.Image, rc);
}
You can draw the content of picturebox simply using DrawToBitmap method:
For example:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Red, new Rectangle(10, 10, 100, 100));
}
private void button1_Click(object sender, EventArgs e)
{
this.printDocument1.Print();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
var bmp=new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
this.pictureBox1.DrawToBitmap(bmp,this.pictureBox1.ClientRectangle);
e.Graphics.DrawImageUnscaled(bmp, 0, 0);
}
And here is the printed result:
How can I crop an image in a pictureBox that shows in Stretch mode?
I draw a rectangle in pictureBox :
void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
//pictureBox1.Image.Clone();
xUp = e.X;
yUp = e.Y;
Rectangle rec = new Rectangle(xDown, yDown, Math.Abs(xUp - xDown), Math.Abs(yUp - yDown));
using (Pen pen = new Pen(Color.YellowGreen, 3))
{
pictureBox1.CreateGraphics().DrawRectangle(pen, rec);
}
rectCropArea = rec;
}
void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
pictureBox1.Invalidate();
xDown = e.X;
yDown = e.Y;
}
and crop the selected part with :
private void btnCrop_Click(object sender, EventArgs e)
{
try
{
pictureBox3.Refresh();
//Prepare a new Bitmap on which the cropped image will be drawn
Bitmap sourceBitmap = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
Graphics g = pictureBox3.CreateGraphics();
//Draw the image on the Graphics object with the new dimesions
g.DrawImage(sourceBitmap, new Rectangle(0, 0, pictureBox3.Width, pictureBox3.Height), rectCropArea, GraphicsUnit.Pixel);
sourceBitmap.Dispose();
}
catch (Exception ex)
{
}
}
but the quality of the cropped image is very low because it cropped the stretch Image not the original image. How can I crop the original image with size of rectangle that User drawing in pictureBox?
I changed pictureBox1_MouseUp code to :
void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
xUp = e.X;
yUp = e.Y;
Rectangle rec = new Rectangle(xDown, yDown, Math.Abs(xUp - xDown), Math.Abs(yUp - yDown));
using (Pen pen = new Pen(Color.YellowGreen, 3))
{
pictureBox1.CreateGraphics().DrawRectangle(pen, rec);
}
xDown = xDown * pictureBox1.Image.Width / pictureBox1.Width;
yDown = yDown * pictureBox1.Image.Height / pictureBox1.Height;
xUp = xUp * pictureBox1.Image.Width / pictureBox1.Width;
yUp = yUp * pictureBox1.Image.Height / pictureBox1.Height;
rectCropArea = new Rectangle(xDown, yDown, Math.Abs(xUp - xDown), Math.Abs(yUp - yDown));
}
And it's worked. Thanks to 'Hans Passant' for his answer.
I have drawn and saved the Rectangle on the image i loaded in the picture box. How i like to draw multiple rectangles for that i tried array in the rectangle but it gives error ("Object reference not set to an instance of an object." (Null reference Exception was unhandled).
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (mybitmap == null)
{
mybitmap = new Bitmap(sz.Width, sz.Height);
}
rect[count] = new Rectangle(e.X, e.Y, 0, 0);
this.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (stayToolStripMenuItem.Checked == true)
{
switch (e.Button)
{
case MouseButtons.Left:
{
rect[count] = new Rectangle(rect[count].Left, rect[count].Top, e.X - rect[count].Left, e.Y - rect[count].Top);
pictureBox1.Invalidate();
count++:
break;
}
}
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (stayToolStripMenuItem.Checked == true)
{
button1.Visible = true;
button2.Visible = true;
if (mybitmap == null)
{
return;
}
using (g = Graphics.FromImage(mybitmap))
{
using (Pen pen = new Pen(Color.Red, 2))
{
//g.Clear(Color.Transparent);
e.Graphics.DrawRectangle(pen, rect);
label1.Top = rect[count].Top; label1[count].Left = rect[count].Left; label1.Width = rect[count].Width;
label1.Height = rect[count].Height;
if (label1.TextAlign == ContentAlignment.TopLeft)
{
e.Graphics.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
g.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
g.DrawRectangle(pen, rect[count]);
}
}
}
}
}
How can i do this.....
You're incrementing the count variable after filling the rect array. By the time pictureBox1_Paint is executed, this increment has already taken place, so rect[count] is now a null reference, which you then try to draw :)
Also, there appears to be a compiler error in pictureBox1_MouseDown. The count++ inside the switch statement doesn't belong to any case block. Put it before the break; statement.
I imagine your intention is something like this:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (mybitmap == null)
return;
using (g = Graphics.FromImage(mybitmap))
using (Pen pen = new Pen(Color.Red, 2))
{
g.Clear(Color.Transparent);
for (int i = 0; i < count; i++)
{
// Code to draw rect[i], instead of rect[count]
}
}
}
How large is your rect array, by the way? Arrays do not automatically grow to accommodate your needs. You may want to look at using List<Rectangle> instead.
Have change the code little bit. Instead of mouse move event used Mouse click event.
On using mouse move event it calls every time when mouse move on the picture box. so list rectangle count gets increased. for this i used mouse click event.
When list rectangle added in Mouse down event, it's only get the values for height and width of the rectangle (if use (0,0,e.X,e.Y))and also rectangle always starts from top left corner (not able to start the rectangle point where user likes) and it's gets only X and Y values (if use(e.X, e.Y,0,0))
to over come this I used the list rectangle in the mouse click event, so I get all values.
List<Rectangle> rectangles = new List<Rectangle>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (stayToolStripMenuItem.Checked == true)
{
if (mybitmap == null)
{
mybitmap = new Bitmap(sz.Width, sz.Height);
}
rect = new Rectangle(e.X, e.Y, 0, 0);
this.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (stayToolStripMenuItem.Checked == true)
{
button1.Visible = true;
button2.Visible = true;
if (mybitmap == null)
{
return;
}
using (g = Graphics.FromImage(mybitmap))
{
using (Pen pen = new Pen(Color.Red, 2))
{
//g.Clear(Color.Transparent);
e.Graphics.DrawRectangle(pen, rect);
label1.Top = rect.Top; label1.Left = rect.Left; label1.Width = rect.Width;
label1.Height = rect.Height;
if (label1.TextAlign == ContentAlignment.TopLeft)
{
e.Graphics.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
g.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
g.DrawRectangle(pen, rect);
}
}
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
rectangles.Add(rect);
pictureBox1.Invalidate();
f = 0;
}
}
What ever rectangle I draw get saved in the list rectangles and get saved when i saved the work (could see all the drawn rectangles when i opened the saved file).
Now the problem is, when I draw a new rectangle the previous one get disappeared (on run time. However this added in list rectangle).
How to display all the rectangles drawn on run time, so user can know how many rectangles drawn and where.