?
Solved

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

Posted on 2006-07-19
10
Medium Priority
?
622 Views
Last Modified: 2008-01-09
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
Comment
Question by:Skytide
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
10 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 17141549
I always have to ask, how would you do it with VB.NET?

Bob
0
 

Author Comment

by:Skytide
ID: 17141561
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
 

Author Comment

by:Skytide
ID: 17141583
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.

 
LVL 96

Expert Comment

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

Bob
0
 

Author Comment

by:Skytide
ID: 17141866
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
 

Author Comment

by:Skytide
ID: 17142196
I figured out an alternative.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 17142273
Awesome!!!  What did you finally find?  

Bob
0
 

Author Comment

by:Skytide
ID: 17142560
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
 
LVL 1

Accepted Solution

by:
GhostMod earned 0 total points
ID: 17168441
Closed, 500 points refunded.

GhostMod
Community Support Moderator
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have developed many web applications with asp & asp.net and to add and use a dropdownlist was always a very simple task, but with the new asp.net, setting the value is a bit tricky and its not similar to the old traditional method. So in this a…
IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question