I want to save digit signatire which I create using pictruebox control to jpeg or png(doesn't matter which file extension). After saving picture it shows black picture. How to avoid black background and save what really is drawn on the picturebox to jpg or png. My code:
public Form4()
{
InitializeComponent();
bm = new Bitmap(pic.Width, pic.Height);
g = Graphics.FromImage(bm);
pic.Image = bm;
}
Bitmap bm;
private void button1_Click(object sender, EventArgs e) // button save to jpg file
{
Bitmap bmp = bm.Clone(new Rectangle(0, 0, pic.Width, pic.Height), bm.PixelFormat);
bmp.Save("Signature.jpg",ImageFormat.Jpeg);
bmp.Dispose();
}
How to avoid this result:
enter image description here
//Code for drawing a signature:
float firstX = 0;
float firstY = 0;
float LastX = 0;
float LastY = 0;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
LastX = e.X;
LastY = e.Y;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
firstX = e.X;
firstY = e.Y;
pictureBox1_Paint(this, null);
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.Black, 7);
g = pic.CreateGraphics();
g.DrawLine(pen, firstX, firstY, LastX, LastY);
LastX = firstX;
LastY = firstY;
}
Related
I use the code provided by Erno with some modification like using DrawRect instead of FillRect to draw the selected area.
You can see the sample code in this thread :
How to select an area on a PictureBox.Image with mouse in C#
private Point RectStartPoint;
private Rectangle Rect = new Rectangle();
private Pen pen = new Pen(Color.Black, 2);
private void VisuelArchive_Load(object sender, EventArgs e)
{
pictureBox1.ImageLocation = fichierArchive;
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
}
private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
Point tempEndPoint = e.Location;
Rect.Location = new Point(Math.Min(RectStartPoint.X, tempEndPoint.X), Math.Min(RectStartPoint.Y, tempEndPoint.Y));
Rect.Size = new Size(Math.Abs(RectStartPoint.X - tempEndPoint.X), Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
pictureBox1.Invalidate();
}
private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// Determine the initial rectangle coordinates...
RectStartPoint = e.Location;
Invalidate();
}
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
// Draw the rectangle...
if (pictureBox1.Image != null)
{
if (Rect != null && Rect.Width > 0 && Rect.Height > 0)
{
e.Graphics.DrawRectangle(pen, Rect);
}
}
}
However I have some problem saving the selected area in a Jpg. I use this code but it seems that the Rect references are not good for that, i save a nearby area not the exact location.
Someone have an idea about how to save the exact location on the PictureBox Image ?
private void ButtonExport_Click(object sender, EventArgs e)
{
//exporter la sélection
Bitmap bmp = new Bitmap(Rect.Size.Width,Rect.Size.Height);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawImage(pictureBox1.Image, new Rectangle(0, 0, Rect.Size.Width, Rect.Size.Height), Rect, GraphicsUnit.Pixel);
}
bmp.Save(Directory.GetCurrentDirectory() + "\\Archives\\" + numFiche.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
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.
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:
I am attempting to save an image as modified by graphics tools such as pens and shapes that can be drawn onto the image. I have done this using a panel with background image and trying to set up a bit map that will save changes within this panel:
private void saveToolStripButton_Click(object sender, EventArgs e)
{
//sets panel1 contents as bit map to be saved at set locations
int width = panel1.Size.Width;
int height = panel1.Size.Height;
using (Bitmap bmp = new Bitmap(width, height))
{
panel1.DrawToBitmap(bmp, new Rectangle(0, 0, width, height));
bmp.Save(#"C:\Users\Me\Pics\testBitmap.jpeg", ImageFormat.Jpeg);
}
MessageBox.Show("Your image has been saved");
}
Once the save button is clicked, the image saves ok but the changes made with the graphics tools do not show up. Can anyone suggest a solution?
Here is some code regarding the graphics tool i've set up for use within the panel:
{
InitializeComponent();
//Create graphics object in panel1
g = panel1.CreateGraphics();
}
private void btnExit2_Click(object sender, EventArgs e)
{
this.Close();
}
Graphics g;
//set a drawing boolean
bool draw = false;
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
draw = true;
if (drawSq)
{
SolidBrush brush = new SolidBrush(Color.FromArgb(128, 255, 0, 0));
if (toolStripTextBox1.Text != "")
{
g.FillRectangle(brush, e.X, e.Y, Convert.ToInt32(toolStripTextBox1.Text), Convert.ToInt32(toolStripTextBox1.Text));
}
else if (toolStripTextBox1.Text == "")
{
MessageBox.Show("Please enter a shape size");
}
draw = false;
drawSq = false;
}
}
and more:
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
draw = false;
mouseX = null;
mouseY = null;
}
//null values allow freehand style drawing
int? mouseX = null;
int? mouseY = null;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
//creates a pen tool and sets properties by mouse location
if (draw)
{
Pen pen = new Pen(btnColor.ForeColor, float.Parse(txtBox1.Text));
g.DrawLine(pen, new Point(mouseX ?? e.X, mouseY ?? e.Y), new Point(e.X, e.Y));
mouseX = e.X;
mouseY = e.Y;
}
}
Let's try to fix this.
Start by creating your image first:
Bitmap bmp;
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
bmp = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height);
}
Now when you want to draw on it:
void panel1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
using (Graphics g = Graphics.FromImage(bmp)) {
g.FillEllipse(Brushes.Red, new Rectangle(e.X - 4, e.Y - 4, 8, 8));
}
panel1.Invalidate();
}
}
And display the results:
void panel1_Paint(object sender, PaintEventArgs e) {
e.Graphics.DrawImage(bmp, Point.Empty);
}
To save, just use your bitmap:
bmp.Save(#"c:\filename.png", ImageFormat.Png);
Use Double buffering with Panel to avoid the flickering.
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);
}
}
}
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.