• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 626
  • Last Modified:

Resize Images Using GDI ---- Error with Gif Files

Hello. I found this excellent article and class about resizing images using GDI. Here is the code:

using System;
using System.Drawing;
using System.IO;

namespace ImageHelper
{
    public class ImageResize
    {
        private double m_width, m_height;
        private bool m_use_aspect = true;
        private bool m_use_percentage = false;
        private string m_image_path;
        private Image m_src_image, m_dst_image;
        private ImageResize m_cache;
        private Graphics m_graphics;

        public string File
        {
            get { return m_image_path; }
            set { m_image_path = value; }
        }

        public Image Image
        {
            get { return m_src_image; }
            set { m_src_image = value; }
        }

        public bool PreserveAspectRatio
        {
            get { return m_use_aspect; }
            set { m_use_aspect = value; }
        }

        public bool UsePercentages
        {
            get { return m_use_percentage; }
            set { m_use_percentage = value; }
        }

        public double Width
        {
            get { return m_width; }
            set { m_width = value; }
        }

        public double Height
        {
            get { return m_height; }
            set { m_height = value; }
        }

        protected virtual bool IsSameSrcImage(ImageResize other)
        {
            if (other != null)
            {
                return (File == other.File
                    && Image == other.Image);
            }

            return false;
        }

        protected virtual bool IsSameDstImage(ImageResize other)
        {
            if (other != null)
            {
                return (Width == other.Width
                    && Height == other.Height
                    && UsePercentages == other.UsePercentages
                    && PreserveAspectRatio == other.PreserveAspectRatio);
            }

            return false;
        }

        public virtual Image GetThumbnail()
        {
            // Flag whether a new image is required
            bool recalculate = false;
            double new_width = Width;
            double new_height = Height;

            // Is there a cached source image available? If not,
            // load the image if a filename was specified; otherwise
            // use the image in the Image property
            if (!IsSameSrcImage(m_cache))
            {
                if (m_image_path.Length > 0)
                {
                    // Load via stream rather than Image.FromFile to release the file
                    // handle immediately
                    if (m_src_image != null)
                        m_src_image.Dispose();
                        // Wrap the FileStream in a "using" directive, to ensure the handle
                        // gets closed when the object goes out of scope
                        using (Stream stream = new FileStream(m_image_path, FileMode.Open))
                            m_src_image = Image.FromStream(stream);

                        recalculate = true;
                   
                }
            }

            // Check whether the required destination image properties have
            // changed
            if (!IsSameDstImage(m_cache))
            {
                // Yes, so we need to recalculate.
                // If you opted to specify width and height as percentages of the original
                // image's width and height, compute these now
                if (UsePercentages)
                {
                    if (Width != 0)
                    {
                        new_width = (double)m_src_image.Width * Width / 100;

                        if (PreserveAspectRatio)
                        {
                            new_height = new_width * m_src_image.Height / (double)m_src_image.Width;
                        }
                    }

                    if (Height != 0)
                    {
                        new_height = (double)m_src_image.Height * Height / 100;

                        if (PreserveAspectRatio)
                        {
                            new_width = new_height * m_src_image.Width / (double)m_src_image.Height;
                        }
                    }
                }
                else
                {
                    // If you specified an aspect ratio and absolute width or height, then calculate this
                    // now; if you accidentally specified both a width and height, ignore the
                    // PreserveAspectRatio flag
                    if (PreserveAspectRatio)
                    {
                        if (Width != 0 && Height == 0)
                        {
                            new_height = (Width / (double)m_src_image.Width) * m_src_image.Height;
                        }
                        else if (Height != 0 && Width == 0)
                        {
                            new_width = (Height / (double)m_src_image.Height) * m_src_image.Width;
                        }
                    }
                }

                recalculate = true;
            }

            if (recalculate)
            {
                // Calculate the new image
                if (m_dst_image != null)
                {
                    m_dst_image.Dispose();
                    m_graphics.Dispose();
                }

                Bitmap bitmap = new Bitmap((int)new_width, (int)new_height, m_src_image.PixelFormat);
                m_graphics = Graphics.FromImage(bitmap);
                m_graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                m_graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

                m_graphics.DrawImage(m_src_image, 0, 0, bitmap.Width, bitmap.Height);
                m_dst_image = bitmap;

                // Cache the image and its associated settings
                m_cache = this.MemberwiseClone() as ImageResize;
            }

            return m_dst_image;

        }

        ~ImageResize()
        {
            // Free resources
            if (m_dst_image != null)
            {
                m_dst_image.Dispose();
                m_graphics.Dispose();
            }

            if (m_src_image != null)
                m_src_image.Dispose();
        }
    }
}

This works great with Jpeg images:

Dim o As New ImageHelper.ImageResize
o.File = myFilePath
o.Height = 500
o.GetThumbnail.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)

but when I try to use this on a Gif, I get an error ("A Graphics object cannot be created from an image that has an indexed pixel format")

Dim o As New ImageHelper.ImageResize
o.File = myFilePath
o.Height = 500
o.GetThumbnail.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif)

Does anyone know how I can fix the class to work with Gifs? I'm only good with VB.net so I don't know how to modify the C# class. Thanks.
0
Skytide
Asked:
Skytide
  • 5
  • 3
1 Solution
 
Bob LearnedCommented:
I always have to ask, how would you do it with VB.NET?

Bob
0
 
SkytideAuthor Commented:
On the flip side, I don't really need to fix the code to handle Gifs, if someone has a good way to resize Gif files without making it looked very dithered. I tried to use the GetThumbnailImage method and someone elses resize method, but they all create bad quality Gifs.

I also found an article on color quantization (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/colorquant.asp), but I still don't know what to do. Am I suppose to extract the palette from the original gif and apply it to the resized one? Please help. Thanks.
0
 
SkytideAuthor Commented:
Bob. Yeah, I wish I knew the anser to doing it with VB.net. I tried a C# to VB.net converter, but it didn't work. However, I figured out how to use C# and VB.net classes in my project. But like the comment above, I don't really need to fix the C# class. I just need a way to resize Gifs well. (Although I'd prefer a fix, since it will mean less coding :-p ). Thanks.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Bob LearnedCommented:
I don't work with GIFs, all JPEGs and PNG files, since they the same file size and better color rendering.

Bob
0
 
SkytideAuthor Commented:
Ok, so I experimented a little with the C# code and figured out where the error is occuring:

m_graphics = Graphics.FromImage(bitmap);

I put a try, catch statement and decided (from other articles I have found) to redraw the image:

                try
                {
                    m_graphics = Graphics.FromImage(bitmap);
                }
                catch
                {
                    Bitmap bmpNew = new Bitmap(m_src_image.Width, m_src_image.Height);
                    m_graphics = Graphics.FromImage(bmpNew);
                    m_graphics.DrawImage(m_src_image, new Rectangle(0, 0, m_src_image.Width, m_src_image.Height), 0, 0, m_src_image.Width, m_src_image.Height, GraphicsUnit.Pixel);
                }

This resizes my gif, BUT my gif file is completely black. Any ideas?
0
 
SkytideAuthor Commented:
I figured out an alternative.
0
 
Bob LearnedCommented:
Awesome!!!  What did you finally find?  

Bob
0
 
SkytideAuthor Commented:
Well as far as the gif goes, I can do some smoothing to make it a little better. Otherwise (according to online stuff), I'll have to use some unsafe code to make the Gif Palette. Most of my users will be using Jpegs anyways....

I still used the Try/Catch statement to work with the Gif image. My C# code was wrong though (since I'm a VB person....). But I figured it out:

catch
                {
                    Bitmap bmpNew = new Bitmap(bitmap.Width, bitmap.Height);
                    m_graphics = Graphics.FromImage(bmpNew);
                    m_graphics.DrawImage(m_src_image, new Rectangle(0, 0, m_src_image.Width, m_src_image.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel);
                    m_graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    m_graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

                    m_graphics.DrawImage(m_src_image, 0, 0, bitmap.Width, bitmap.Height);
                    m_dst_image = bmpNew;
                }

0
 
GhostModCommented:
Closed, 500 points refunded.

GhostMod
Community Support Moderator
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now