How to save and load in panel? - c#

I want to save image from panel to bitmap and then I want to load the saved image after my Form comes out of minimizing mode.
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(#"C:\Test");
panel1.BackgroundImage = Image.FromFile(#"C:\Test");
And what event should I use for minimizing event?
P.S. I am a C# beginner.

EDITED
Drawing your panel's contents. This should be done inside its Paint event handler, like this:
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Pen p = new Pen(Color.Red, 3))
{
// get the panel's Graphics instance
Graphics gr = e.Graphics;
// draw to panel
gr.DrawLine(p, new Point(30, 30), new Point(80, 120));
gr.DrawEllipse(p, 30, 30, 80, 120);
}
}
Saving your panel's contents as an image. This part should be done somewhere else (for example, when you click on a "Save" button):
private void saveButton_Click(object sender, EventArgs e)
{
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:\testBitmap.jpeg", ImageFormat.Jpeg);
}
}

Related

Refresh does not refresh

I made an user control and I draw a rectangle directly in the window, like this (this is a simplified version):
private int rec_len = 200;
private void Draw_()
{
Pen pn = new Pen( Color.Black, WIDTH_LINE );
Graphics graph = this.CreateGraphics();
graph.Clear( Color.Transparent );
this.Refresh();
graph.DrawRectangle( pn, 20, 10, rec_len, 40 );
this.Refresh();
graph.Dispose();
}
public void button_Build_Click( object sender, EventArgs e )
{ rec_len += 10; Draw_(); }
The strange thing is that the second refresh actually poses a problem: if I comment it out, the rectangle is visible, if I let it in the code, the rectangle is not visible. In the real code I have to draw more than a rectangle and I want the refresh at the end, otherwise the background is visible between the moment I erase old drawing and the moment the new one is ready.
The surface of a control is not stored: When you paint on a control, the drawing is not saved and need to be redrawn each time the control is repainted (After a refresh for example). To create a persistante graphic, you can create a bitmap, draw on the bitmap and assign this bitmap to the BackgroundImage property.
Bitmap bmp = new Bitmap(WIDTH, HEIGHT);
void Initialize()
{
this.BackgroundImage = bmp;
}
private int rec_len = 200;
private void Draw_()
{
Pen pn = new Pen(Color.Black, WIDTH_LINE);
using (Graphics graph = Graphics.FromImage(bmp))
{
graph.Clear(Color.Transparent);
this.Refresh();
graph.DrawRectangle(pn, 20, 10, rec_len, 40);
this.Refresh();
}
}
public void button_Build_Click(object sender, EventArgs e) { rec_len += 10; Draw_(); }

Saving System.Graphics to bitmap not working

I've created program for drawing. It uses System.graphics to draw rectangles etc. on panel1 in form.
Graphics
Mouse draw event:
Draw
I want to get art from panel1 as a bitmap, tried this code:
using (var bmp = new Bitmap(panel1.Width, panel1.Height))
{
panel1.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save("output.png", System.Drawing.Imaging.ImageFormat.Jpeg);
}
but it generates background color of panel1 in image
Add a handler to the Paint event of the panel somewhere (e.g. form constructor):
panel1.Paint += panel1_Paint;
[Re]draw any graphics in the event:
void panel1_Paint(object sender, PaintEventArgs e)
{
DrawLine(e.Graphics);
}
When saving, your code should work just fine:
private void button1_Click(object sender, EventArgs e)
{
using (var bmp = new Bitmap(panel1.Width, panel1.Height))
{
panel1.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save("c:\\temp\\output.png", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}

Crop and load tiled image in picturebox c#

I have a tiled image like https://i.imgsafe.org/67397f9.png and want to load its parts as image for a picture box in some mouse events. actually I want simulate button behavior.
Bitmap source = new Bitmap(Properties.Resources.btn_close);
public Bitmap CropImage(Bitmap srcbmp, Rectangle dstcrp)
{
Bitmap bmp = new Bitmap(dstcrp.Width, dstcrp.Height);
Graphics gfx = Graphics.FromImage(bmp);
gfx.DrawImage(srcbmp, 0, 0, dstcrp, GraphicsUnit.Pixel);
return bmp;
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
Rectangle section = new Rectangle(new Point(0, 93), new Size(51, 30));
pictureBox1.Image = CropImage(source, section);
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
Rectangle section = new Rectangle(new Point(0, 93), new Size(51, 30));
pictureBox1.Image = CropImage(source, section);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Rectangle section = new Rectangle(new Point(0, 62), new Size(51, 30));
pictureBox1.Image = CropImage(source, section);
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
Rectangle section = new Rectangle(new Point(0, 0), new Size(51, 30));
pictureBox1.Image = CropImage(source, section);
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Rectangle section = new Rectangle(new Point(0, 0), new Size(51, 30));
pictureBox1.Image = CropImage(source, section);
}
this is my codes that crop sections of image and load as bitmap for picture box.
I think it is not very professional and may have some memory usage problems, etc...
is there any simple way to do this?
2 solutions which i can think of
When you first load the form you can declare 4 image/bitmap variables 1 for each Mouse State Mouse Down, Leave Up and Enter so instead of recrating the images again and again you can just change the image when time is right.
var cropCoordinates= new Rectangle(new Point(0, 0), new Size(51, 30));
var onMouseDownImage = new Bitmap(Properties.Resources.btn_close);
You can have 4 different image boxes for each state (layered 1 on top of the other )and show or hide when the time is needed

Screenshot of Mainform shows subform. How to make sure subform is closed?

I want to make a screenshot of a Panel on my Mainform. This screenshot should be made after the user chose some Options on a subform. At the beginning everything went fine but now the screenshot contains parts of the subform.
The subform gets opened like this:
private void Bexport_Click(object sender, EventArgs e) //button
{
ex = new Export();
initexForm();
ex.FormClosed += this.exFormClosed;
ex.TXTfilename.Focus();
ex.ShowDialog(this);
}
The function which makes the screenshot:
void exFormClosed(object sender, EventArgs e)
{
try
{
System.Drawing.Rectangle bounds = Mainpanel.Bounds;
bounds.Width = bounds.Width - 6;
bounds.Height = bounds.Height - 4;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(
Mainpanel.PointToScreen(new Point()).X + 3,
Mainpanel.PointToScreen(new Point()).Y + 2, 0,
0, bounds.Size);
}
bitmap.Save(Application.StartupPath + temppic.bmp);
Document doc = new Document();
...
I used the events FormClosed and FormClosing, both with similar results. Then I tried to hide the subform with ex.Hide() but it hid the whole program, means the screenshot showed the desktop from behind the program.
Anybody an idea how to make sure that the subform is closed before making the screenshot?
Jonathan
The problem might be that the main form didn't have time to repaint after the subform closed.
this.Update();
will force the Form to repaint (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.update.aspx)
What you have to do is create a dummy form that's the size of the control you want to draw then add the control to the dummy form and show the form and draw the control from the dummy.
public Bitmap ControlToBitmap(Control ctrl)
{
Bitmap image = new Bitmap(ctrl.Width, ctrl.Height);
//Create form
Form f = new Form();
//add control to the form
f.Controls.Add(ctrl);
//set the size of the form to the size of the control
f.Size = ctrl.Size;
//draw the control to the bitmap
ctrl.DrawToBitmap(image, new Rectangle(0, 0, ctrl.Width, ctrl.Height));
//dispose the form
f.Dispose();
return image;
}
So if you call it like this:
void exFormClosed(object sender, EventArgs e)
{
Bitmap bitmap ControlToBitmap(Mainpanel);
bitmap.Save(Application.StartupPath + temppic.bmp);
Document doc = new Document();
...
This will work even if the form has already been closed.
void exFormClosed(object sender, EventArgs e)
{
try
{
Application.DoEvents();
System.Drawing.Rectangle bounds = Mainpanel.Bounds;
bounds.Width = bounds.Width - 6;
bounds.Height = bounds.Height - 4;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(
Mainpanel.PointToScreen(new Point()).X + 3,
Mainpanel.PointToScreen(new Point()).Y + 2,
0, 0, bounds.Size);
}
...

How to draw graphics to a form upon form startup

Im trying to draw a graphic on a form upon form startup. I've tried putting the graphic components inside the form constructer, but i cannot seem to get it working. This is what i've got so far.
public partial class Form3 : Form
{
public Form3()
{
System.Drawing.Graphics graphics = this.CreateGraphics();
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(100, 100, 200, 200);
graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
}
Any and all help will be awesome,
Thanks guys
One solution would be to use a Bitmap, e.g.
Bitmap b = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(b);
... // Draw
this.BackgroundImage = b;
Otherwise, you'll need to handle the Paint event, whereat you can draw directly to the graphics context each time the form is invalidated. e.g.
this.Paint += Form1_Paint;
...
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(100, 100, 200, 200);
g.DrawEllipse(System.Drawing.Pens.Black, rectangle);
g.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(100, 100, 200, 200);
e.Graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
e.Graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}

Categories