Answered by:
A Graphics object cannot be created from an image that has an indexed pixel format.

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 DPIDim aGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(aBitmap)Dim MemStream As New MemoryStream()aGraphic.SmoothingMode = Drawing2D.SmoothingMode.HighSpeedaGraphic.InterpolationMode = Drawing2D.InterpolationMode.DefaultaGraphic.DrawImage(theImage, 0, 0, aBitmap.Width, aBitmap.Height)theImage.Dispose()aBitmap.PixelFormat = PixelFormat.Format1bppIndexedaBitmap.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...
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