How to get an image of what System.Drawing.Graphics object draws? - c#

See the following method:
void Paint(System.Drawing.Graphics g)
{
//How can I start record what 'g' will draw to an image object?
g.DrawLine(0,0,50,50);
g.DrawImage(...);
..
..
etc.
}
Now how can I get An Image about what 'g' drew?
Thanks :)

You could try...
using (Graphics g=Graphics.FromImage(inImage))
{
g.Clear(Color.White);
g.DrawLine(0,0,50,50);
}
This will then draw the line on to the image. Just make sure the image is big enough...
Also you can draw straight on to a form by overriding the OnPaint event and getting the graphics object from the eventArgs.

You can do this one
Bitmap bmp;
...
{
InitializeComponent();
bmp = new Bitmap(this.Width,this.Height,Graphics.FromHwnd(this.Handle));
}
void Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = Graphics.FromImage(bmp);
g.DrawLine(0,0,50,50);
..
..
e.Graphics.DrawImage(bmp,0,0);
}

Related

CopyFromScreen Copy not correct location only on Touchdisplays

In my c# i use CopyFromScreen
On many pc's the script ar always ok,
the panel1 in my Form will be saved as image
but when i use touchdisplays in the image is evrything but newer the panel1
i can not understand why?
private void buttonInsert_Click(object sender, EventArgs e)
{
Image bmp = new Bitmap(panel1.Width, panel1.Height);
var gg = Graphics.FromImage(bmp);
var rect = panel1.RectangleToScreen(panel1.ClientRectangle);
gg.CopyFromScreen(rect.Location, Point.Empty, panel1.Size);
bmp.Save(#"C:\Temp\test.jpg", ImageFormat.Jpeg);
Graphics g = panel1.CreateGraphics();
g.Clear(Color.WhiteSmoke);
}
thx for your help
I found it out, the problem was the windows scaling. When i set it on 100% the Problem solved.
thx a lot

WinForms - How do I run a function with PaintEventArgs when the form is loaded?

I'm trying to understand the graphics, and in the Graphics.FromImage documentation, it has this as an example:
private void FromImageImage(PaintEventArgs e)
{
// Create image.
Image imageFile = Image.FromFile("SampImag.jpg");
// Create graphics object for alteration.
Graphics newGraphics = Graphics.FromImage(imageFile);
// Alter image.
newGraphics.FillRectangle(new SolidBrush(Color.Black), 100, 50, 100, 100);
// Draw image to screen.
e.Graphics.DrawImage(imageFile, new PointF(0.0F, 0.0F));
// Dispose of graphics object.
newGraphics.Dispose();
}
I'm new to C# and Windows Forms and am struggling to understand how this all fits together. How is this code run, say when the form first loads or when a button is pressed?
Maybe this will help. I have an example of both drawing on Paint events but also drawing on top of an existing Image. I created a form with two picture boxes. One for each case. pictureBox1 has an event handler for the .Paint event, while pictureBox2 is only drawn when a button is pressed.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
pictureBox1.BackColor=Color.Black;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// The code below will draw on the surface of pictureBox1
// It gets triggered automatically by Windows, or by
// calling .Invalidate() or .Refresh() on the picture box.
DrawGraphics(e.Graphics, pictureBox1.ClientRectangle);
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
// The code below will draw on an existing image shown in pictureBox2
var img = new Bitmap(pictureBox2.Image);
var g = Graphics.FromImage(img);
DrawGraphics(g, pictureBox2.ClientRectangle);
pictureBox2.Image=img;
}
void DrawGraphics(Graphics g, Rectangle target)
{
// draw a red rectangle around the moon
g.DrawRectangle(Pens.Red, 130, 69, 8, 8);
}
}
So when you launch the application a red rectangle appears on the left only, because the button hasn't been pressed yet.
and when the button is pressed, the red rectangle appears on top of the image displayed in pictureBox2.
Nothing dramatic, but it does the job. So depending on the mode of operation you need (user graphics, or image annotations) use the example code to understand how to do it.

How to draw multiple ellipse in the same panel

I am trying to draw some ellipse in the same panel, and the coordinators are determined by mouse click. Here is my code, this code can only draw one circle. The newer circle is always updating the older circle on the panel. So there is always only one circle.
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;
panel1.Invalidate();
}
Graphics g;
private void panel1_Paint(object sender, PaintEventArgs e)
{
g = panel1.CreateGraphics();
g.FillEllipse(Brushes.Red, x,y, 10, 10);
}
Winforms graphics basic rule #1 : Never use control.CreateGraphics! Never try to cache a Graphics object! Either draw into a Bitmap bmp using a Graphics g = Graphics.FromImage(bmp) or in the Paint event of a control, using the e.Graphics parameter..
You can test the persistance of your graphics by doing a Minimize/Maximize sequence..
The correct way is to keep a list of things to draw and whenever that list changes Invalidate the control you draw on. All drawing should be in the Paint event, using e.Graphics there!
This will let you draw many circles:
List<Point> points = new List<Point>(); // List<T> is wonderful !
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
points.Add(e.Location);
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
g = e.Graphics; // only ever use this one for persistent graphics!!
foreach( Point pt in points)
g.FillEllipse(Brushes.Red, pt.X, pt.Y, 10, 10);
}
delete them all by
points.Clear();
Delete the last one by
points.Remove(points.Last());
For other sizes store List<Rectangle> instead. For more complex drawing create a DrawAction class of your own to hold pens, colors or even rotations and other shapes etc..

C# Draw on a PictureBox

Suppose i have an PictureBox with image assigned to it, and i just want to draw a smaller bitmap above it.
This is my code:
Bitmap a = Getimage();//just a small function generates a new image.
Bitmap f = (Bitmap) pictureBox1.Image;//getting the picturebox image.
Graphics g = Graphics.FromImage(f);
g.DrawImage(a,150,200);//draws a on f at (150,200).
PictureBox1.Image=f;
However, in my program it runs on a loop in a seperated thread, so im getting an Error:
Object is in use elsewhere
Is there any way to draw directly to the Picturebox itself? instead of getting it's bitmap and draw, and assign again? Or at least how may i solve the above exception?
Thanks.
this will help you
public Form1()
{
InitializeComponent();
new Thread(MyDraw).Start();
}
private void MyDraw()
{
while(true)
{
Invoke(new Action(DrawItem));
Thread.Sleep(1000);
}
}
private void DrawItem()
{
using (var graphics = Graphics.FromImage(pictureBox1.Image))
{
graphics.DrawString("Hello", new Font("Arial", 20), Brushes.Yellow, PointF.Empty);
}
}

Cast Graphics to Image in C#

I have a pictureBox on a Windows Form.
I do the following to load a PNG file into it.
Bitmap bm = (Bitmap)Image.FromFile("Image.PNG", true);
Bitmap tmp;
public Form1() {
InitializeComponent();
this.tmp = new Bitmap(bm.Width, bm.Height);
}
private void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.DrawImage(this.bm, new Rectangle(0, 0, tmp.Width, tmp.Height), 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel);
}
However, I need to draw things on the image and then have the result displayed again. Drawing rectangles can only be done via the Graphics class.
I'd need to draw the needed rectangles on the image, make it an instance of the Image class again and save that to this.bm
I can add a button that executes this.pictureBox1.Refresh();, forcing the pictureBox to be painted again, but I can't cast Graphics to Image. Because of that, I can't save the edits to the this.bm bitmap.
That's my problem, and I see no way out.
What you need to do is use the Graphics.FromImage method, which will allow you to draw directly on the image instead of the temporary Graphics object create from within the Paint method:
using (Graphics g = Graphics.FromImage(this.bm))
{
g.DrawRectangle(...);
}
Do this instead of (or in addition to) hooking the Paint method of the PictureBox. This way, you won't need to use a temporary image or Graphics object at all, and when you're finished modifying the original bitmap (this.bm) then you can invoke pictureBox1.Refresh to force the image to be re-displayed.

Categories