0

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.

Mister Crabs
  • 41
  • 1
  • 5
  • 1
    In your first example if you have using() block for FileStream then you don't need to call Close(), Dispose(). As I see in the first example you are calling Clone() so you have an another object but the second disposes the object. Check out these: https://stackoverflow.com/questions/25723855/outofmemoryexception-out-of-memory-system-drawing-graphics-fromimagehttps://social.msdn.microsoft.com/Forums/en-US/4aac43fa-cccb-4bf7-b37e-58ec5351ab80/outofmemoryexception-when-using-graphicsfromimage?forum=csharplanguage – Major Dec 12 '18 at 21:49
  • I think the solution is this: In Graphics, "out of memory" Exception mostly occurred when the image.propertyitems throws some exception. At that, time we need to store the image in stream and again get the image from the stream. – Major Dec 12 '18 at 21:50

2 Answers2

1

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)

Mister Crabs
  • 41
  • 1
  • 5
  • Oh,the answer above (which I didn't notice right away) looks more detailed. That answer doesn't make much sense anymore. – Mister Crabs Dec 13 '18 at 10:23
0

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.

Jimi
  • 29,621
  • 8
  • 43
  • 61