locked
A Graphics object cannot be created from an image that has an indexed pixel format. RRS feed

  • Question

  • User1090916182 posted

    Hi

    I'm really struggling to create a method that resizes JPG/GIF images then saves them back out.  I've Google'd the error now for 2 days but can't find a solution that I can get working.  I know this is a really common error so am hoping somebody can show me the code to get this working, which will help others in the future.

    Basically I need to load an image from a file, then resize it to some pre-determined size, then save it back in the original format.  I get an Exception however when I try with GIF images (A Graphics object cannot be created from an image that has an indexed pixel format).  I know the correct way is to fork the logic to process each file type differently, but I can't work out the GIF way.

    Can somebody please enlighten me?  Here is my code so far...


    Dim workingImage As Image = Image.FromFile(myFileName)
    Dim outputBitmap As New Bitmap(newWidth, newHeight, workingImage.PixelFormat)
    Dim ImageDrawer As Graphics = Graphics.FromImage(outputBitmap) ' Exception thrown here for GIF's
    ImageDrawer.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
    ImageDrawer.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
    ImageDrawer.DrawImage(workingImage, 0, 0, outputBitmap.Width, outputBitmap.Height)
    Dim finalImageFormat As Imaging.ImageFormat = Imaging.ImageFormat.Jpeg
    If System.IO.Path.GetExtension(myFileName).ToLower = ".gif" Then finalImageFormat = Imaging.ImageFormat.Gif End If outputBitmap.Save(HttpContext.Current.Server.MapPath(DestinationDirectory & "/" & fileNameAndExt), finalImageFormat)
      
    Tuesday, December 18, 2007 6:44 AM

Answers

  • User-1944457978 posted

    Instead of: 

    Dim workingImage As Image = Image.FromFile(myFileName)
    Dim outputBitmap As New Bitmap(newWidth, newHeight, workingImage.PixelFormat)
    Dim ImageDrawer As Graphics = Graphics.FromImage(outputBitmap) ' Exception thrown here for GIF's
    Try this:
    Dim workingImage as image = Image.FromFile(myFileName)
    Dim TempImg As Image = New Bitmap(WorkingImage.Width, WorkingImage.Height)
    Dim ImageDrawer as Graphics = Graphics.FromImage(TempImg) 

    Don't worry about the original PixelFormat until you are ready to write the graphic back out to a file.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, March 12, 2008 6:00 PM

All replies

  • User987997965 posted

    Try using a MemoryStream instead.  Sorry my example is in C# but you should be able to easily convert it:

     

    try
    
    {
    
        byte[] imgData = getData(<PATHTOFILE>);
    
        System.Drawing.Image img = System.Drawing.Image.FromStream(new MemoryStream(imgData));
    
        Bitmap img = new Bitmap(new Bitmap( img ));
    
    }
    
    catch (Exception ex)
    
    {
    
        
    
    }
    
     
    
    public byte[] getData(string filePath)
    
    {
    
        FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    
        BinaryReader br = new BinaryReader(fs);
    
        byte[] data = br.ReadBytes((int)fs.Length);
    
        br.Close();
    
        fs.Close();
    
        return data;
    
    }
    
     
    Tuesday, December 18, 2007 9:02 AM
  • User1090916182 posted

    Hi.

    Same error I'm afraid. 

    I believe this problem involves working with the image, not reading it as a file.  Either way it's very frustrating.

    Tuesday, December 18, 2007 9:15 AM
  • Tuesday, December 18, 2007 9:45 AM
  • User1090916182 posted

    Hi,

    Yes I have seen this page already (along with lots more on my 2 days of hunting!).  The obvious question therefore is "How do you raise an image depth" ?

    I can't find any full working example in ASP.NET 2 that allows a GIF or a JPG to be resized without using the infamous getThumbnail() method!  Even if I could convert a GIF to a JPG using GDI+ that might be okay (although image quality will suffer for the GIF's), but I can't find examples of that either! 

    Tuesday, December 18, 2007 9:53 AM
  • User987997965 posted

    Hmm.  Let me try a few things and I will get back to you later on today.  If you could send me the image that is giving you the problem to: douglas.c.parsons *[at]* gmail *[dot]* com

    Tuesday, December 18, 2007 10:31 AM
  • User1090916182 posted

    Hmm.  Let me try a few things and I will get back to you later on today.

     

    Thank you.

    If you could send me the image that is giving you the problem to: douglas.c.parsons *[at]* gmail *[dot]* com

     

    Any GIF throws the error.  I know it is because of the indexed colour structure of GIF files in general, but I can't find a single example of how to work with it using .NET/GDI+

    Tuesday, December 18, 2007 10:46 AM
  • User1090916182 posted

    Hang on, I'm wrong.  Not ALL gif's cause the error.

    I presume this is because of the different techniques to index the colours perhaps, or maybe compression codecs... who knows?!?

    Either way, here's a hyperlink to a gif that does cause the error:

    http://webstyleguide.com/graphics/graphics/7.21.gif

    Tuesday, December 18, 2007 10:53 AM
  • User1090916182 posted

    I've been continuing my search for an answer here and by dissecting code from other people's questions I have found a way to make it work.

    The old code was this to create a new bitmap:

    Dim outputBitmap As New Bitmap(newWidth, newHeight, workingImage.PixelFormat)
     

    But if I replace it with this:

    Dim outputBitmap As New Bitmap(newWidth, newHeight)
     

    Then the error does not get thrown (so far).  I will investigate why this is (I presume without specifying the PixelFormat, GDI uses a generic one for the new bitmap instance?).  Either way I'd really appreciate some clarification!

    Tuesday, December 18, 2007 11:51 AM
  • User-1944457978 posted

    Instead of: 

    Dim workingImage As Image = Image.FromFile(myFileName)
    Dim outputBitmap As New Bitmap(newWidth, newHeight, workingImage.PixelFormat)
    Dim ImageDrawer As Graphics = Graphics.FromImage(outputBitmap) ' Exception thrown here for GIF's
    Try this:
    Dim workingImage as image = Image.FromFile(myFileName)
    Dim TempImg As Image = New Bitmap(WorkingImage.Width, WorkingImage.Height)
    Dim ImageDrawer as Graphics = Graphics.FromImage(TempImg) 

    Don't worry about the original PixelFormat until you are ready to write the graphic back out to a file.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, March 12, 2008 6:00 PM
  • User1090916182 posted

     Hi bwkeller

    Yes I eventually used this approach.  I wish I knew about it sooner!  The .NET framework is a lot more powerful than I imagined when it comes to image manipulation - I never thought that you would 'paint' the image and then decide on the output format.  I thought it would be the other way around.

    Just out of interest, does the .NET framework use any particular picture type when working with images (i.e. for the raw canvas) ?

    -- R
     

    Thursday, March 13, 2008 11:33 AM
  • User1708755508 posted

     instead of

    Dim outputBitmap As New Bitmap(newWidth, newHeight, workingImage.PixelFormat)
     
    give PixelFormat.Format24bppRgb 
    Wednesday, February 4, 2009 5:59 AM
  • User2120868776 posted

    Wait.  I don't get it.  How do you set the pixelformat outside of the bitmap's constructor method?

    This is my code:


          Dim theImage As Image = Image.FromFile(sourceName.FullName)
          Dim aBitmap As System.Drawing.Bitmap = New System.Drawing.Bitmap(theImage.Width, theImage.Height)
          aBitmap.SetResolution(300, 300) ' 300 DPI
          Dim aGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(aBitmap)
          Dim MemStream As New MemoryStream()
          aGraphic.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
          aGraphic.InterpolationMode = Drawing2D.InterpolationMode.Default
          aGraphic.DrawImage(theImage, 0, 0, aBitmap.Width, aBitmap.Height)
          theImage.Dispose()
          aBitmap.PixelFormat = PixelFormat.Format1bppIndexed
          aBitmap.Save(MemStream, ImageFormat.Png)

          Dim theImage As Image = Image.FromFile(sourceName.FullName)

          Dim aBitmap As System.Drawing.Bitmap = New System.Drawing.Bitmap(theImage.Width, theImage.Height)

          aBitmap.SetResolution(300, 300) ' 300 DPI

          Dim aGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(aBitmap)

          Dim MemStream As New MemoryStream()


          aGraphic.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed

          aGraphic.InterpolationMode = Drawing2D.InterpolationMode.Default

          aGraphic.DrawImage(theImage, 0, 0, aBitmap.Width, aBitmap.Height)

          theImage.Dispose()


          aBitmap.PixelFormat = PixelFormat.Format1bppIndexed ' <----- This line of code doesn't work.  I sure wish it did.

          aBitmap.Save(MemStream, ImageFormat.Png)


    Wednesday, March 3, 2010 2:19 PM
  • User1090916182 posted

    Wait.  I don't get it.  How do you set the pixelformat outside of the bitmap's constructor method?

    I'm not sure if you can.  I suppose the GDI would need to know the pixel format before it started doing anything with the image, so it would make sense to be part of the constructor method... Undecided

    Thursday, March 4, 2010 3:20 AM
  • User1591353686 posted

    If you use PNG format image, you can change the re-edit the image save the type to PNG24, it's fixed.

    Wednesday, April 14, 2010 5:11 AM