GIF quality

liming

Perch
Anybody tried to produce a dynamic GIF on the fly here? like thumbnails?

I get really bad quality GIFs using .net 2.0, I saw a few articles on OctTree quantiziation, but when I uploded it here to JodoHost, because the code requires High trust permission, jodo denies it.

Anybody has similar code available for improving gif image quality?

many thanks.
 
HI, yep I've made GIFs with .NET and not had a problem with the quality. And they were for insertion into a PDF document, so had to be hi res and good quality.

Make sure you are creating the bitmap in 24bit colour, so that when you do the save-as-GIF, it has a full 24bit palette to do it's antialiasing with before it optimises the palette.

Note as in the code below you need to set SmoothingMode before you draw objects you want to have antialiased:
Code:
    Dim pic As New System.Drawing.Bitmap(200, 200, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    Dim g As Graphics = Graphics.FromImage(pic)
    g.Clear(Drawing.Color.White) ' blank the image
    ' draw some stuff
    Dim silverpen As New Pen(ColorTranslator.FromHtml("#CCCCCC"), 10)
    Dim blackpen As New Pen(Drawing.Color.Black, 3)
    Dim redpen As New Pen(Drawing.Color.Red, 4)
    g.DrawLine(silverpen, 17, 80, 130, 80)

    ' antialias the following objects **important to set this**
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias

    g.DrawEllipse(blackpen, 15, 15, 110, 110)
    g.DrawEllipse(redpen, 11, 11, 118, 118)

    ' Save as GIF
    pic.Save(<your data stream object>, System.Drawing.Imaging.ImageFormat.Gif)

hth
 
Hi Antic,

Thanks for the code. After reading it, as of a matter of fact,I found out if my bitmap is composed of solid colors from RGB like, red, blue, green, the produced gif does have good quality.

The bad thing is if my bitmap loads a background image (with gradient), then the color palette needs to hold a lot more color and when save() into ImageFormat.GIF, a lot of the color are diethered, and looks bad.

Too bad jodo won't let me upload that OctTree dll. otheriwse, I could sleep by now :(
 
Gradients naturally never look any good in GIF format, no matter what you do. It's the format, not the library that's most likely your limitation in that respect. Try JPG, you might get a better result.

Jodo can't allow any and all DLLs on servers, not in a shared environment. .NET has excellent graphics support, I doubt another DLL could do the job much better if at all. It's just the GIF format.
 
Can you post the code you're using to produce your image? What you're experiencing there is a pattern-based dithering method, which is producing that hashing effect. If you can post your code (from where you create/load your bitmat to where you save it) and I'll see why you are getting that effect. I don't get that effect at all when I use GDI+ saving to GIF from a 24-bit bitmap.
 
Yep.

Here is my httpHandler

string disheader = "inline; filename=\"" + myinfo.FileName + "\"";
HttpContext.Current.Response.AppendHeader("Content-Disposition", disheader);
HttpContext.Current.Response.ContentType = "image/"+myinfo.FileImageType;

log.Debug("image type is :"+myinfo.FileImageType.ToUpper());
log.Debug("image name is :"+myinfo.FileName);
if(myinfo.FileImageType.ToUpper().Equals("JPEG"))
{
log.Debug("Encoding JPEP Image for "+myinfo.FileName);
System.Drawing.Imaging.ImageCodecInfo[] objEncoders = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders();
System.Drawing.Imaging.ImageCodecInfo objUsedEncoder=null;
foreach(System.Drawing.Imaging.ImageCodecInfo objEncoder in objEncoders)
{
if (objEncoder.MimeType == HttpContext.Current.Response.ContentType.ToLower())
{
objUsedEncoder = objEncoder;
}
}

System.Drawing.Imaging.EncoderParameters objEncoderParams = new System.Drawing.Imaging.EncoderParameters(1);
objEncoderParams.Param[0]= new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
img.Save(HttpContext.Current.Response.OutputStream, objUsedEncoder,objEncoderParams);
}
else if(myinfo.FileImageType.ToUpper().Equals("GIF"))
{
log.Debug("Output GIF Image for "+myinfo.FileName);

try
{
//ImageManipulation.OctreeQuantizer quantizer = new ImageManipulation.OctreeQuantizer(255, 8);
//System.Drawing.Bitmap quantized = quantizer.Quantize(img);
//quantized.Save(HttpContext.Current.Response.OutputStream,ImageFormat.Gif);
}
catch(Exception e)
{
log.Debug(e.Message+e.StackTrace);
}
img.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Gif);
}

HttpContext.Current.Response.End();
img.Dispose();
 
Ok, I'm with ya now! I used the default GDI conversion from a JPG to a GIF and got the same nasty results you did. The good results I got before was because I was drawing lines and stuff on the canvas in plain colours, not loading a full-colour image.

Anyway, found a workable solution, just download the .net library attached below, put it in your /bin folder, and reference it in your project.

The use the following code to utilise the octree quantization method (this is VB):
Code:
    Dim pic As New System.Drawing.Bitmap(Server.MapPath("myimage.jpg"))
    Dim quantized As Bitmap = New ImageQuantization.OctreeQuantizer(255, 8).Quantize(pic)

    Response.ContentType = "image/gif"
    quantized.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif)

    pic.Dispose()
    Response.End()
I'll have a crack at the c# code too, tho it's not my forte'...
Code:
    System.Drawing.Bitmap pic = new System.Drawing.Bitmap(Server.MapPath("myimage.jpg"));
    Bitmap quantized = new ImageQuantization.OctreeQuantizer(255, 8).Quantize(pic);

    Response.ContentType = "image/gif";
    quantized.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);

    pic.Dispose();
    Response.End();

Also attached is the GIF output it gave me, from a colour-gradated JPG, which turned out pretty good. I scored the library from this page, which also has the c# source for the quantization library. The library seems to use the Octree method you are after, as well as providing fixed-palette and greyscale quantizers as well.

All you need to do is upload the dll into your bin folder along with your own project dll.

Hope that helps! It sure helped me... I must thank you for posting that question, because it's something I will actually be using now too!

But please remember, for all our sakes, cache your images to disk once you have created them, and reuse them where possible! This goes for whatever image tool you use, whether it's this one, or AspImage or whatever. Please don't create the same images on the fly on every page hit, otherwise you'll monopolise server resources that we all have to share. :thumb:
 

Attachments

  • ImageQuantization.zip
    5.4 KB · Views: 226
  • myimage.gif
    myimage.gif
    5.8 KB · Views: 94
ahh..darn it. really sorry Antic. I just used your code and again works beatifully on my local machine.. but this is what I get now on server

http://dotnetv2.civion.com/

still permission deneid :( how come you don't have this problem? are you using .net 1.1 or .net 2.0? I'm using .net 2.0
 
liming,

At this time we can't increase the permissions on asp.net 2 for security purposes, there are some things that hsphere could do to manage .net 2 better and make it more secure at the "high trust" setting.

However, I am not sure what your purpose is here, but if you would like, I could setup a folder for you in your domain, create an app folder on it, and have it running asp.net 1.1 and you could generate these on the fly from there from the same domain(with a "folder" look to the user) if you wish. I know it is not ideal but let me know if that can work for you, I can help you set it up.
 
Hi Stephen,

Great suggestion!! Finally solved it.

I don't know know why I never thought about this.. after read your comment about .net 1.1, I uploaded this dll to a .net 1.1 folder in a subdomin of mine, and it loads without any issue!!! Beatiful.

Now all i have to do is point this service from that .net 1.1 subdomain and images will come back.

Thanks for this idea. A beautiful way to "hack" around this issue.

and thanks again, Antic. You are a great man!

Liming
 
heh no probs, I was just testing it on a live account of mine and it worked first time without issues. Perhaps that server is still .net 1.1?

http://www.activeorg.com/test/cimage/

That's where I set it up and it worked ok. I'm using Visual Studio 2003, which (maybe) always uses .net 1.1, don't know.

So I was just about to say sorry it works for me. :) Glad you got it going, thanks for the help Stephen. This is why Jodo is such a cool place to host. :thumb:
 
antic, 1.1 is default unless 2.0 is requested, and only newer servers have 2.0, so you are still on 1.1
 
Back
Top