When I run the code below to take screenshot, I get an error like A generic error occurred in GDI+. How can I resolve this issue or any other way to take screenshot of current window?
protected void Page_Load(object sender, EventArgs e) {
Bitmap bitmap = new Bitmap(100, 200);
Graphics graphics = Graphics.FromImage(bitmap as System.Drawing.Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save("c:\\screenshot.jpeg", ImageFormat.Jpeg);
}
You should use
bitmap.Save(#"c:\\screenshot.jpeg", ImageFormat.Jpeg);
Also why you define bitmap again, it's not needed:
Graphics graphics = Graphics.FromImage(bitmap);
Related
I need to save picturebox loaded png file with picturebox backgroud colour.
I've try with these.
But result is showing as a blank image.
help me..
private void bunifuThinButton24_Click(object sender, EventArgs e)
{
Bitmap bmp1 = new Bitmap(pictureBox1.Width, pictureBox1.Height, pictureBox1.CreateGraphics());
bmp1.Save(#"C:\Users\...\New folder4\ xx.jpg");
}
Bitmap bmp1 = new Bitmap(pictureBox1.Width, pictureBox1.Height, pictureBox1.CreateGraphics()); creates a new blank bitmap image with the resolution of pictureBox1's graphics object. you need to draw your picturebox in this bitmap. You can do this using the picturebox's DrawToBitmap function.
void bunifuThinButton24_Click(object sender, EventArgs e)
{
Bitmap bmp1 = new Bitmap(pictureBox1.Width, pictureBox1.Height, pictureBox1.CreateGraphics());
// fill in bitmap with the picturebox's backcolor
using (Graphics g = Graphics.FromImage(bmp1))
{
using (Brush drawBrush = new SolidBrush(pictureBox1.BackColor))
{
g.FillRectangle(drawBrush, new Rectangle(0, 0, bmp1.Width, bmp1.Height));
}
}
// draw picturebox on bitmap
pictureBox1.DrawToBitmap(bmp1, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
bmp1.Save(#"C:\Users\...\New folder4\ xx.jpg");
}
In c# and Visual Studio Windows forms I have loaded an image into a picture box (pictureBox2) and then cropped it and show in another picture box (pictureBox3).
Now I want to save what is inside pictureBox3 as an image file.
How can I do this?
private void crop_bttn_Click(object sender, EventArgs e)
{
Image crop = GetCopyImage("grayScale.jpg");
pictureBox2.Image = crop;
Bitmap sourceBitmap = new Bitmap(pictureBox2.Image,
pictureBox2.Width, pictureBox2.Height);
Graphics g = pictureBox3.CreateGraphics();
g.DrawImage(sourceBitmap, new Rectangle(0, 0,
pictureBox3.Width, pictureBox3.Height), rectCropArea, GraphicsUnit.Pixel);
sourceBitmap.Dispose();
}
Never use control.CreateGraphics! 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..
Here is a cropping code that draws into a new Bitmap and that makes use of your controls etc but changes a few things:
It uses a Graphics object that is created from a new Bitmap
It make use of using clauses to make sure it won't leak
It takes the size of the pictureBox3.ClientSize so it won't include any borders..
private void crop_bttn_Click(object sender, EventArgs e)
{
Image crop = GetCopyImage("grayScale.jpg");
pictureBox2.Image = crop;
Bitmap targetBitmap = new Bitmap(pictureBox3.ClientSize.Width,
pictureBox3.ClientSize.Height);
using (Bitmap sourceBitmap = new Bitmap(pictureBox2.Image,
pictureBox2.ClientSize.Width, pictureBox2.ClientSize.Height))
{
using (Graphics g = Graphics.FromImage(targetBitmap))
{
g.DrawImage(sourceBitmap, new Rectangle(0, 0,
pictureBox3.ClientSize.Width, pictureBox3.ClientSize.Height),
rectCropArea, GraphicsUnit.Pixel);
}
}
if (pictureBox3.Image != null) pictureBox3.Image.Dispose();
pictureBox3.Image = targetBitmap;
targetBitmap.Save(somename, someFormat);
}
The alternative would be to..:
move all your code to the Paint event
replace the Graphics g = pictureBox3.CreateGraphics(); be Graphics g = e.Graphics;
insert these two lines to the click event:
Bitmap targetBitmap = new Bitmap(pictureBox3.ClientSize.Width,
pictureBox3.ClientSize.Height);
pictureBox3.DrawToBitmap(targetBitmap, pictureBox3.ClientRectangle);
The method PictureBox.CreateGraphics() should not be used unless you know what you are doing because it can cause some not-so-obvious problems. For example, in you scenario, the image in pictureBox3 will disappear when you minimize or resize the window.
A better way is to draw to a bitmap, which you also can save:
var croppedImage = new Bitmap(pictureBox3.Width, pictureBox3.Height);
var g = Graphics.FromImage(croppedImage);
g.DrawImage(crop, new Point(0, 0), rectCropArea, GraphicsUnit.Pixel);
g.Dispose();
//Now you can save the bitmap
croppedImage.Save(...);
pictureBox3.Image = croppedImage;
Btw, please use more reasonable variable names, especially for pictureBox1..3.
I try to do double buffer using BufferedGraphics. When i use BufferedGraphics.Render method background of my image changes to black. Here the simple code, that illustrate my issue
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e) {
Paint += new PaintEventHandler(Form1_Paint);
}
private void print(Bitmap image, PaintEventArgs e) {
Graphics graphicsObj = e.Graphics;
graphicsObj.DrawImage(image, 60, 10);
graphicsObj.Dispose();
}
private void Form1_Paint(object sender, PaintEventArgs e) {
Rectangle rect = Screen.PrimaryScreen.Bounds;
PixelFormat pf;
pf = PixelFormat.Format32bppArgb;
Bitmap image = new Bitmap(rect.Width, rect.Height, pf);
Graphics g = Graphics.FromImage(image);
g.Clear(Color.Orange);
BufferedGraphicsContext context = new BufferedGraphicsContext();
BufferedGraphics buffer = context.Allocate(g, new Rectangle(0, 0, rect.Width + 20, rect.Height + 20));
buffer.Render(g);
print(image, e);
}
}
I expect to see orange rectangle on my screen, but it's black. I can't understand why this happen. Help me please :)
buffer.Render(g) renders the contents of the buffer to the graphics object. This means that the orange color is being overwritten by the empty buffer.
You'll have to choose between using BufferedGraphicsContext or creating a buffer yourself (the image).
The following would fix your issue using just the image:
...
Bitmap image = new Bitmap(rect.Width, rect.Height, pf);
using (Graphics g = Graphics.FromImage(image))
{
g.Clear(Color.Orange);
}
print(image, e);
You could also still use BufferedGraphicsContext, but you'd have to write the image to its Graphics property:
print(image, buffer.Graphics); // render your image to the buffer
buffer.Render(e.Graphics); // render the buffer to the paint event graphics
By the way, don't Dispose the graphics object provided by Form1_Paint (you currently do that in the print() method.
As a response to your comment, BufferedGraphicsContext seems to not support transparency when rendering it to the "main" graphics object, but you can draw transparent images to it correctly. The following example shows how the buffer is filled with a red color, and then a transparent image with a blue line is drawn to it:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (BufferedGraphicsContext context = new BufferedGraphicsContext())
using (BufferedGraphics buffer = context.Allocate(e.Graphics, new Rectangle(0, 0, 120, 120)))
{
// Create a bitmap with just a blue line on it
Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawLine(Pens.Blue, 0, 0, 100, 100);
}
// Fill a red square
buffer.Graphics.FillRectangle(Brushes.Red, 5, 5, 110, 110);
// Draw the blue-line image over the red square area
buffer.Graphics.DrawImage(bmp, 10, 10);
// Render the buffer to the underlying graphics
buffer.Render(e.Graphics);
}
}
In the result you can clearly see the blue line from the image over the red color in the background buffer (the red background is not overwritten) and there's a black border around the red rectangle where no background pixels where drawn.
Im trying to save a file that i am using im getting a GDI+ error because im trying to save over the source file im using. Any solutions?
Example:
private void Form1_Load(object sender, EventArgs e)
{
Bitmap sourceImage = new Bitmap("images/sourceImage.jpg");
sourceImage = CropBitmap(sourceImage, 0, 0, sourceImage.Width, 50);
sourceImage.Save("images/sourceImage.jpg", ImageFormat.Jpeg);
}
public Bitmap CropBitmap(Bitmap bitmap, int cropX, int cropY, int cropWidth, int cropHeight)
{
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat);
return cropped;
}
See the documentation for this constructor. Specifically the section that reads:
The file remains locked until the Bitmap is disposed.
You must dispose the sourceImage before saving a new one. So, use different variables:
var sourceImage = new Bitmap("images/sourceImage.jpg");
var croppedImage = CropBitmap(sourceImage, 0, 0, sourceImage.Width, 50);
sourceImage.Dispose();
croppedImage.Save("images/sourceImage.jpg", ImageFormat.Jpeg);
croppedImage.Dispose();
When you replace sourceImage with the reference from CropBitmap, the original file is still open. You will have to Dispose of it after reading it from the file, open a new Bitmap and save it overwriting the existing one.
private void Form1_Load(object sender, EventArgs e)
{
Bitmap sourceImage = new Bitmap("images/sourceImage.jpg");
Bitmap targetImage = CropBitmap(sourceImage, 0, 0, sourceImage.Width, 50);
sourceImage.Dispose();
targetImage.Save("images/sourceImage.jpg", ImageFormat.Jpeg);
}
MSDN Bitmap documentation
The file remains locked until the Bitmap is disposed.
I'm trying to draw text on a bitmap which is then shown in a picture box. Code is the following:
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap("filename.bmp");
RectangleF rectf = new RectangleF(70, 90, 90, 50);
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawString("myText", new Font("Tahoma", 8), Brushes.Black, rectf);
g.Flush();
pictureBox1.Image = bmp;
}
When I run the program and press the button2 I get an error.
It says:
An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Incorrect parameter.
I can't find any mistake there. What could be wrong?
You need to specify an existing file name. The more flexible solution is to just specify dimensions of your bitmap. For example, next code creates a text in a bitmap
Bitmap bmp = new Bitmap(200, 200);
//your code
bmp.Save(#"D:\filename.bmp");
g.Flush();
creates next image at D:\filename.bmp
If you want to alter existing bitmap by adding new text, use Image.FromFile method, like:
Bitmap bmp = (Bitmap)Image.FromFile(#"D:\filename.bmp");