Reputation: 41
The code is very simple: I Press the button, the picture is loaded into the PictureBox.
private void button1_Click(object sender, EventArgs e)
{
using (FileStream stream = File.OpenRead(FullName))
{
pictureBox1.Image = (Bitmap)Bitmap.FromStream(stream).Clone();
stream.Close();
stream.Dispose();
}
}
But when from other function\events I use Graphics on PictureBox'e, it swears that there is not enough memory on Graphics.FromImage. No matter what I do with this schedule. Example:
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.Clear(Color.FromArgb(0, 255, 255, 255));
pictureBox1.Invalidate();
}
The question is, why can I do anything I want with Graphics before uploading a picture to the PictureBox:cut, fill,draw; but after uploading a picture I can't? p.s. Picture tried different sizes. The same picture works before uploading(it was already in the default pictureBox) and does not work after uploading to the pictureBox. Walked quite a lot of forums on this subject, but my case(or the most similar case) is not found.
Upvotes: 0
Views: 564
Reputation: 32248
You have 3 alternatives:
1) Assign the Image.FromStream()
result without cloning it: the PictureBox Control preferes to act on its own on the underlying stream (see the .Net Source about the PictureBox.Load() method).
private void button1_Click(object sender, EventArgs e)
{
using (FileStream stream = File.OpenRead(FullName))
{
pictureBox1.Image = Bitmap.FromStream(stream);
}
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.Clear(Color.FromArgb(0, 255, 255, 255));
}
}
2) Perform all the operations inside the using block. The stream will still be valid at this point:
using (FileStream stream = File.OpenRead(FullName)
{
pictureBox1.Image = (Image)Image.FromStream(stream).Clone();
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.Clear(Color.FromArgb(0, 255, 255, 255));
}
}
3) Use the Load() method directly.
pictureBox1.Load(FullName);
All methods will end up using the PictureBox Control internal InstallNewImage() (.Net source) method. See how the Image stream
is treated.
Calling Graphics.FromImage()
will not raise an exception anymore.
Upvotes: 0
Reputation: 41
So the problem is in stream,used by Graphics.FromImage. Documentation says,that stream open from Graphics.FromImage must remain open throughout the work with the image. Okay,we can use MemoryStream:
MemoryStream ms;
private void button1_Click(object sender, EventArgs e)
{
ms = new MemoryStream();
using (FileStream stream = File.OpenRead(FullName))
{
stream.CopyTo(ms);
pictureBox1.Image = Bitmap.FromStream(ms);
}
}
private void button2_Click(object sender, EventArgs e)
{
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.Clear(Color.FromArgb(0, 255, 255, 255));
}
}
And image.Clone() need to remove, because stream must have a ref to the same image, not to their copies for correct work. (To be honest, that simply programm can work without MemoryStream)
Upvotes: 1