John Demetriou
John Demetriou

Reputation: 4377

A generic GDI+ error occured at ConvertTo

I am trying to create a byte array from an Image in order to store the data in a blob in MySQL database. There is no need to tell me that Blobs are a bad practice etc etc we already talked and argued on what to use in our case and since it is only one small image file then Blobs are the way to go. This is my code:

ImageConverter converter = new ImageConverter();
byte[] byteImg = (byte[])converter.ConvertTo(original, typeof(byte[]));

I am using C# and Winforms. I keep getting a generic gdi+ error that the original bitmap image cannot be accessed. To check upon this I inserted a line of code before the ImageConverter line to show the original bitmap in a picturebox and it is shown properly so I suppose there is no issue with accessing. I looked up all possible answers here at stackoverflow (and they are plenty) all of them ask to check if I disposed the image, if it is no longer valid etc etc. I have no using in my code nor I dispose the image. The original is in fact a global variable that I am trying to access.

**EDIT I tried storing the image in a picturebox and converting it from the picturebox and it still gives the same error. The exception basically is ObjectDisposedException but I am not disposing it anywhere in my code. If it helps it happens with all images that I am using which are varying in size

**EDIT 2 Posting complete set of code Bitmap resizedImage, original; I declare these two as globals outside of any method. In the following code I read the original image, store it in a bitmap and also create a new Resized Image that fits my needs while maintaining the aspect ratio.

private void imageResize()
        {
            if (string.IsNullOrWhiteSpace(imageLabel.Text))
            {
                flag = false;
                imageLabel.BackColor = Color.FromArgb(252, 240, 109);
            }
            else
            {
                try
                {

                    using (FileStream fs = new System.IO.FileStream(imageLabel.Text, System.IO.FileMode.Open))
                    {

                        original = new Bitmap(fs);
                    }

                    int rectHeight = 100;
                    int rectWidth = 112;
                    if (original.Height == original.Width)
                    {
                        resizedImage = new Bitmap(original, rectHeight, rectHeight);
                    }
                    else
                    {
                        float aspect = original.Width / (float)original.Height;
                        int newWidth, newHeight;
                        newWidth = (int)(rectWidth * aspect);
                        newHeight = (int)(newWidth / aspect);

                        if (newWidth > rectWidth || newHeight > rectHeight)
                        {
                            if (newWidth > newHeight)
                            {
                                newWidth = rectWidth;
                                newHeight = (int)(newWidth / aspect);

                            }
                            else
                            {
                                newHeight = rectHeight;
                                newWidth = (int)(newHeight * aspect);

                            }
                        }
                        resizedImage = new Bitmap(original, newWidth, newHeight);



                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Not supported file type " + ex.Message);
                }
            }
        }

When the user clicks on the upload to DB button it calls the imageResize method and then the following one to send the data.

private void saveData()
        {

            //code for reading rest of the data. 
            //Flag=false if something is wrong with it. Removed it as it has nothing to do
            // with the error. Only string types here
            if (flag)
            {
                DB.Image = original;
                MessageBox.Show("pause");
                MySqlConnection con = new MySqlConnection("server=127.0.0.1;database=testrmaomo;user id=root;password=root;persistsecurityinfo=True");
                con.Open();
                MySqlCommand cmd;
                //convert image to byte array
                ImageConverter converter = new ImageConverter();
                byte[] byteImg = (byte[])converter.ConvertTo(original.Clone(), typeof(byte[]));
                byte[] byteImgPrint = (byte[])converter.ConvertTo(resizedImage.Clone(), typeof(byte[]));

                //check if entry already exists in DB
                cmd = new MySqlCommand("SELECT count(*) FROM logopath;", con);
                StringBuilder sb = new StringBuilder();
               //check if the record exists. If it does update it if not insert it. 
              // Removed as it has nothing to do with the error
            }

The DB.Image=original; line of code was added after the error occurred just to see if original still holds the image. And it does.

**EDIT 3 I found a solution to my problem by creating a temporary Bitmap before converting to a byte array such as

        ImageConverter converter = new ImageConverter();
        Bitmap tmp = new Bitmap(original);
        byte[] byteImg = (byte[])converter.ConvertTo(tmp.Clone(), typeof(byte[]));

Or I think I do since using .Clone() occasionally fixed my issue before. The question is WHY?

Upvotes: 2

Views: 2211

Answers (2)

rjs
rjs

Reputation: 31

You must keep the Stream open. This helped for me. So try this:

FileStream fs = new System.IO.FileStream(imageLabel.Text, System.IO.FileMode.Open))
original = new Bitmap(fs);

You can also read this answer from Jon Skeet: https://stackoverflow.com/a/336396

This could be also interesting for your problem: https://stackoverflow.com/a/1053123

Upvotes: 1

DavidG
DavidG

Reputation: 118937

You may need to clone the bitmap and use that instead:

byte[] byteImg = (byte[])converter.ConvertTo(original.Clone(), typeof(byte[]));

Upvotes: 1

Related Questions