C# winforms draw to bitmap invalid parameter - c#

I have made an application, and i need the function drawbitmap to print my panel. When i push the button (btnUpdate) 12 times or more I get a parameter exception(invalid parameter)on this rule: panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
private void preview()
{
Bitmap bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
pictureBox2.Image = bmp1;
}
private void btnUpdate_Click(object sender, EventArgs e)
{
preview();
}
Can someone help me please?
I can't use the bmp1.Dispose(); function... I get an exeption in the Program.cs file in this line: Application.Run(new Form1());

This could be a case of not disposing the bitmaps when you're done with them. Try this:
panel1.DrawToBitmap(...);
// get old image
Bitmap oldBitmap = pictureBox2.Image as Bitmap;
// set the new image
pictureBox2.Image = bmp1;
// now dispose the old image
if (oldBitmap != null)
{
oldBitmap.Dispose();
}

You have a great big Memory leak there, watch your memory as you click the button 12 clicks and your up to 1GB,
try declaring you Bitmap as a varable and Dispose it before re assigning.
private Bitmap bmp1;
private void preview()
{
if (bmp1 != null)
{
bmp1.Dispose();
}
bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
pictureBox2.Image = bmp1;
}
Or just clear the PictureBox befor assigning a new Bitmap
private void preview()
{
if (pictureBox2.Image != null)
{
pictureBox2.Image.Dispose();
}
Bitmap bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
pictureBox2.Image = bmp1;
}

The problem is fixed by doing this:
private void preview()
{
Bitmap bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
Image img = pictureBox2.Image;
pictureBox2.Image = bmp1;
if (img != null) img.Dispose(); // the first time it'll be null
}
private void btnUpdate_Click(object sender, EventArgs e)
{
preview();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}

Related

Image Captures only blank

I am try Try capture an image of an particular area in my webpage. Below code works fine but issue is it gives me only a blank image with a size of 1.64kb every time.
Function call
protected void btn_Click(object sender, EventArgs e)
{
System.Drawing.Image image = CaptureScreen(50, 99, 930, 450);
image.Save(Server.MapPath("/img/screen.jpg"));
}
Function Definition
public System.Drawing.Image CaptureScreen(int sourceX, int sourceY, int destX, int destY)
{
Bitmap bmp = new Bitmap(930, 430);
Graphics g = Graphics.FromImage(bmp);
Size xx=new Size();
xx.Width=930;
xx.Height=450;
g.CopyFromScreen(sourceX, sourceY, destX, destY, xx);
return bmp;
}

How to check if image object is the same as one from resource?

So I'm trying to create a simple program that just change the picture in a picture box when it's clicked. I'm using just two pictures at the moment so my code for the picture box click event function
looks like that:
private void pictureBox1_Click(object sender, EventArgs e)
{
if (pictureBox1.Image == Labirint.Properties.Resources.first)
pictureBox1.Image = Labirint.Properties.Resources.reitmi;
else if (pictureBox1.Image == Labirint.Properties.Resources.reitmi)
pictureBox1.Image = Labirint.Properties.Resources.first;
}
For some reason the if statement it's not working and the picture don't change.
What should I do?
Note: original code contained bug with second if undoing effect of first if condition would work with fix suggested by Cyral's answer, but adding else did not fix the issue - stepping through the code with else still shows no matches for either image.
if (pictureBox1.Image == Labirint.Properties.Resources.first)
pictureBox1.Image = Labirint.Properties.Resources.reitmi;
if (pictureBox1.Image == Labirint.Properties.Resources.reitmi) // was missing else
pictureBox1.Image = Labirint.Properties.Resources.first;
if (pictureBox1.Image == Labirint.Properties.Resources.first)
There's a trap here that not enough .NET programmers are aware of. Responsible for a lot of programs that run with bloated memory footprints. Using the Labirint.Properties.Resources.xxxx property creates a new image object, it will never match any other image. You need to use the property only once, store the images in a field of your class. Roughly:
private Image first;
private Image reitmi;
public Form1() {
InitializeComponent();
first = Labirint.Properties.Resources.first;
reitmi = Labirint.Properties.Resources.reitmi;
pictureBox1.Image = first;
}
And now you can compare them:
private void pictureBox1_Click(object sender, EventArgs e) {
if (pictureBox1.Image == first) pictureBox1.Image = reitmi;
else pictureBox1.Image = first;
}
And to avoid the memory bloat:
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
first.Dispose();
reitmi.Dispose();
}
You need to use else if, because if the image is first, you set it to reitmi, then you check if it is reitmi, which it now is, and change it back to first. This ends up not appearing to change at all.
if (pictureBox1.Image == Labirint.Properties.Resources.first)
pictureBox1.Image = Labirint.Properties.Resources.reitmi;
else if (pictureBox1.Image == Labirint.Properties.Resources.reitmi)
pictureBox1.Image = Labirint.Properties.Resources.first;
Maybe this code can be a bit large, but works just fine with me, try it:
This is the requeriment:
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Collections;
And here is the code to compare:
// Your Images
Image img1 = pictureBox1.Image;
Image img2 = pictureBox2.Image;
// Now set as bitmap
Bitmap bmp1 = new Bitmap(img1);
Bitmap bmp2 = new Bitmap(img2);
// here will be stored the bitmap data
byte[] byt1 = null;
byte[] byt2 = null;
// Get data of bmp1
var bitmapData = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp1.PixelFormat);
var length = bitmapData.Stride * bitmapData.Height;
//
byt1 = new byte[length];
//
Marshal.Copy(bitmapData.Scan0, byt1, 0, length);
bmp1.UnlockBits(bitmapData);
// Get data of bmp2
var bitmapData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp2.PixelFormat);
var length2 = bitmapData2.Stride * bitmapData2.Height;
//
byt2 = new byte[length2];
//
Marshal.Copy(bitmapData2.Scan0, byt2, 0, length2);
bmp2.UnlockBits(bitmapData2);
// And now compares these arrays
if (StructuralComparisons.StructuralEqualityComparer.Equals(byt1, byt2))
{
MessageBox.Show("Is Equal");
}
else
{
MessageBox.Show("Isn`t equal");
}
this code compares each byte image to generate the result. may have other easier ways.

I can't get my IF statement to fire with Label.BackgroundImage == Properties.Resources.image1 [duplicate]

So I'm trying to create a simple program that just change the picture in a picture box when it's clicked. I'm using just two pictures at the moment so my code for the picture box click event function
looks like that:
private void pictureBox1_Click(object sender, EventArgs e)
{
if (pictureBox1.Image == Labirint.Properties.Resources.first)
pictureBox1.Image = Labirint.Properties.Resources.reitmi;
else if (pictureBox1.Image == Labirint.Properties.Resources.reitmi)
pictureBox1.Image = Labirint.Properties.Resources.first;
}
For some reason the if statement it's not working and the picture don't change.
What should I do?
Note: original code contained bug with second if undoing effect of first if condition would work with fix suggested by Cyral's answer, but adding else did not fix the issue - stepping through the code with else still shows no matches for either image.
if (pictureBox1.Image == Labirint.Properties.Resources.first)
pictureBox1.Image = Labirint.Properties.Resources.reitmi;
if (pictureBox1.Image == Labirint.Properties.Resources.reitmi) // was missing else
pictureBox1.Image = Labirint.Properties.Resources.first;
if (pictureBox1.Image == Labirint.Properties.Resources.first)
There's a trap here that not enough .NET programmers are aware of. Responsible for a lot of programs that run with bloated memory footprints. Using the Labirint.Properties.Resources.xxxx property creates a new image object, it will never match any other image. You need to use the property only once, store the images in a field of your class. Roughly:
private Image first;
private Image reitmi;
public Form1() {
InitializeComponent();
first = Labirint.Properties.Resources.first;
reitmi = Labirint.Properties.Resources.reitmi;
pictureBox1.Image = first;
}
And now you can compare them:
private void pictureBox1_Click(object sender, EventArgs e) {
if (pictureBox1.Image == first) pictureBox1.Image = reitmi;
else pictureBox1.Image = first;
}
And to avoid the memory bloat:
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
first.Dispose();
reitmi.Dispose();
}
You need to use else if, because if the image is first, you set it to reitmi, then you check if it is reitmi, which it now is, and change it back to first. This ends up not appearing to change at all.
if (pictureBox1.Image == Labirint.Properties.Resources.first)
pictureBox1.Image = Labirint.Properties.Resources.reitmi;
else if (pictureBox1.Image == Labirint.Properties.Resources.reitmi)
pictureBox1.Image = Labirint.Properties.Resources.first;
Maybe this code can be a bit large, but works just fine with me, try it:
This is the requeriment:
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Collections;
And here is the code to compare:
// Your Images
Image img1 = pictureBox1.Image;
Image img2 = pictureBox2.Image;
// Now set as bitmap
Bitmap bmp1 = new Bitmap(img1);
Bitmap bmp2 = new Bitmap(img2);
// here will be stored the bitmap data
byte[] byt1 = null;
byte[] byt2 = null;
// Get data of bmp1
var bitmapData = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp1.PixelFormat);
var length = bitmapData.Stride * bitmapData.Height;
//
byt1 = new byte[length];
//
Marshal.Copy(bitmapData.Scan0, byt1, 0, length);
bmp1.UnlockBits(bitmapData);
// Get data of bmp2
var bitmapData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp2.PixelFormat);
var length2 = bitmapData2.Stride * bitmapData2.Height;
//
byt2 = new byte[length2];
//
Marshal.Copy(bitmapData2.Scan0, byt2, 0, length2);
bmp2.UnlockBits(bitmapData2);
// And now compares these arrays
if (StructuralComparisons.StructuralEqualityComparer.Equals(byt1, byt2))
{
MessageBox.Show("Is Equal");
}
else
{
MessageBox.Show("Isn`t equal");
}
this code compares each byte image to generate the result. may have other easier ways.

c# save overwrite image error

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.

bmp Image Resizing and Fit to page in c#

I have Image of width 1171 and height 1181. I need that image into print page using printDocument...So Final image size would be width 596 and height 892. So it covers all area of page without any space.
My problem is I am able to resize it but it does not cover the whole space of page...And with different solution it covers the whole page area but image cutted down.
So what I have to do for solving this issue?
My code as per below...
private void btnPrint_Click(object sender, EventArgs e)
{
btnPrint.Enabled = false;
try
{
printDocument1.Print();
this.Close();
}
catch (Exception err)
{
MessageBox.Show("Printing failed :" + err.Message);
btnPrint.Enabled = true;
}
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Image img = ((PictureBox)pictureBox1).Image;
Bitmap bmp = (Bitmap)img;
bmp.Save("abcc");
Bitmap bitmap = new Bitmap(bmp, new Size(892, 596));
// Bitmap b = ResizeBitmap(bmp, 892, 596);
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
e.Graphics.CompositingMode = CompositingMode.SourceCopy;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.Transform.Scale(0, 0);
e.Graphics.DrawImage(bitmap,new Rectangle(0,0,892,596),new Rectangle(0,0,bmp.Width,bmp.Height),GraphicsUnit.Pixel);
}

Categories

Resources