Question Loading GIF Picture From File Works But Not From Memory

SiamIT

Active member
Joined
Aug 3, 2021
Messages
44
Programming Experience
5-10
I am facing a weird issue, i need to load GIF image/picture from memory to picture box. It's works fine for non GIF picture, but for GIF it throws GDI error.

C#:
A generic error occurred in GDI+.

here is my test codes to show you the error

C#:
    public partial class Form1 : Form
    {
        string imgFilePath;
        Image memoryIMG;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            imgFilePath = @"f:\Temp\NW\_bak\exclamationIMG.gif"; //this is an gif (animated) image, it throws gdi error
            //imgFilePath = @"f:\Temp\NW\_bak\banLangIMG.png"; //this does work fine
        }

        private void DirectAccessButton_Click(object sender, EventArgs e)
        {
            //direct access from file just work fine
            TestPicturebox.Image = Image.FromFile(imgFilePath);
        }

        private void LoadToMemoryButton_Click(object sender, EventArgs e)
        {
            //this proc load the file into memory
            using(FileStream imgStream = new FileStream(imgFilePath, FileMode.Open, FileAccess.Read))
            {
                memoryIMG = Image.FromStream(imgStream);
            }
        }

        private void MemoryAccessButton_Click(object sender, EventArgs e)
        {
            //this try to show the image from memory and throws error in case of gif but not on png file
            TestPicturebox.Image = memoryIMG;
        }

        private void TestMemoryButton_Click(object sender, EventArgs e)
        {
            //i tried to save to local file from memory and the image viewer can show the file fine that's means memory is good
            string tempPath = Path.GetTempFileName();
            memoryIMG.Save(tempPath);
        }
    }


any idea why is this happening?

thanks in advance

best regards
 
I suspect the issue is that, because the GIF is animated, an attempt is made to read data from the source stream of Image object when the frame changes. That would fail because the Stream is closed, so an exception is thrown. It may be that you have no choice but to maintain an open Stream, in which case you should try using a MemoryStream if there's some reason you can't use a FileStream.
 
I suspect the issue is that, because the GIF is animated, an attempt is made to read data from the source stream of Image object when the frame changes. That would fail because the Stream is closed, so an exception is thrown. It may be that you have no choice but to maintain an open Stream, in which case you should try using a MemoryStream if there's some reason you can't use a FileStream.

you are right, i can't use file stream as, images are stored in resource files and read on memory (image variables). And calls every time needed...

so, instead of using stored images in memory:
C#:
public static Image waitingIMG, exitIMG, exclamationIMG, infoIMG, errorIMG, questionIMG, banLangIMG, engLangIMG, devBanner, promoBanner;

can i use multiple memory stream, and keep it open for the life of the app, will it cause any issue if there are many opened memory stream?
C#:
public static MemoryStream waitingIMG, exitIMG, exclamationIMG, infoIMG, errorIMG, questionIMG, banLangIMG, engLangIMG, devBanner, promoBanner;

sorry for my bad English but hope that make sense?

thanks in advance

best regards
 
If the image data is coming from a resource, there is no need to copy into a memory stream. Just keep the resource stream open.
 
If the image data is coming from a resource, there is no need to copy into a memory stream. Just keep the resource stream open.

thanks a lot for your reply sir, though i am not very good at stream things, but i am not using regular resource stream. my resources (like images, etc.) are encoded in custom format archive file, i decode, get the decode byte, then create memory stream out of the bytes data. then create the img objects using those memory stream.

now as per "jmcilhinney" suggestion, i just want to skip those image objects and rather open/use memory stream. and my concern is whether will it affect my app by any means if those memory steams keeps open for the life of the app?

hope i am clear so far?

thanks in advance both of you

best regards
 
Yes, it would affect your app. The more memory you are holding on to, the more impact it would on the working set of your application. Depending on how much true physical RAM your machine has, and what other applications are running on the machine and their corresponding memory usage, the OS may have to do a lot of memory page swaps to and from disk so that each application has the data that it needs. Do some reading about operating systems and virtual memory.
 
I did not tell you to use a MemoryStream and not use an Image. What I said was that you should create the Image from the MemoryStream and keep the stream open. That way, it will not fail if the system tries to go back to the stream later. I don't know for a fact that that is the issue but I have seen many examples of exceptions thrown in such circumstances that were fixed this way.
 
I did not tell you to use a MemoryStream and not use an Image. What I said was that you should create the Image from the MemoryStream and keep the stream open. That way, it will not fail if the system tries to go back to the stream later. I don't know for a fact that that is the issue but I have seen many examples of exceptions thrown in such circumstances that were fixed this way.

then would you please sir, tell me what you suggest me to do?
 
I just told you what to do, for the second time. Create the Image from a MemoryStream and don't close the stream. You obviously already know how to create an Image from a Stream because you're doing it with a FileStream in post #1. Just use a MemoryStream instead but don't dispose it until you're finished using the Image. That means not creating it with a using statement, the specific purpose of which is to automatically dispose the object created at the end of the block.
 
Back
Top Bottom