Poor Image Quality When Resizing a GIF

View: New views
11 Messages — Rating Filter:   Alert me  

Poor Image Quality When Resizing a GIF

by Andy McCurdy-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

Just started using PIL.  I'm attempting to resize a .gif image to a
smaller size, keeping the height/width proportional.  The resize
works, but the resulting image is very grainy.  Resizing the same
image with ImageMagick's convert utility produced a far better quality
image.  I'd rather use PIL if possible since it has a much better API.
 The below code works fine with JPG files.  Am I missing something?

    from PIL import Image

    # original_content is a string of bytes representing the image.
    # the image is not stored locally on disk, so it's fetched from
the storage service as a string
    # and loaded up using a StringIO buffer
    # Have also tried loading the same .gif from a local disk directly
with Image.open('filename.gif'), but image after resize looked grainy
as well
    io = StringIO(original_content)
    pil_image = Image.open (io)

    # docs suggest that the default mode, 'P', won't use the ANTIALIAS
filter, so switch to RGB
    pil_image = pil_image.convert('RGB')


    # ... stuff happens here to figure out what the new width and
height should be

    # tuple representing the new size
    new_size = (new_width, new_height)

    # the actual resize...
    pil_image = pil_image.resize(new_size, Image.ANTIALIAS)

    # save the new image back out to a StringIO buffer -- has to be
sent back to the storage service
    io = StringIO()
    format = 'GIF'   # hardcoded in this example
    pil_image.save(io, format)



Thanks for any help possible.
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Fredrik Lundh :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andy McCurdy wrote:

> Just started using PIL.  I'm attempting to resize a .gif image to a
> smaller size, keeping the height/width proportional.  The resize
> works, but the resulting image is very grainy.

try converting the image to "RGB" first, and use resize(ANTIALIAS) on
the RGB image before converting it back to P.

(if you resize a "P" image as is, you can only use the NEAREST
resampling method.  this works reasonably well for certain kinds of
"graphics", but less so for images that are dithered.  for some kinds of
images, smoothing the RGB image before resizing it might also help.)

</F>

_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Andy McCurdy-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fredrik, thanks for the reply.  I am in fact converting to "RGB"
first... at least I think so.  Here's the code I'm using that produces
bad results:

from PIL import Image

# io is a file handle
pil_image = Image.open(io)

# convert to rgb
pil_image = pil_image.convert('RGB')

# new_width/new_height are calculated to retain the
# current height/width proportions
new_size = (new_width, new_height)

#resize the image
pil_image = pil_image.resize(new_size, Image.ANTIALIAS)

# save the image back to disk
pil_image.save(io, 'GIF')


On Jan 9, 2008 12:28 AM, Fredrik Lundh <fredrik@...> wrote:

> Andy McCurdy wrote:
>
> > Just started using PIL.  I'm attempting to resize a .gif image to a
> > smaller size, keeping the height/width proportional.  The resize
> > works, but the resulting image is very grainy.
>
> try converting the image to "RGB" first, and use resize(ANTIALIAS) on
> the RGB image before converting it back to P.
>
> (if you resize a "P" image as is, you can only use the NEAREST
> resampling method.  this works reasonably well for certain kinds of
> "graphics", but less so for images that are dithered.  for some kinds of
> images, smoothing the RGB image before resizing it might also help.)
>
> </F>
>
> _______________________________________________
> Image-SIG maillist  -  Image-SIG@...
> http://mail.python.org/mailman/listinfo/image-sig
>
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Fredrik Lundh :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andy McCurdy wrote:

> Fredrik, thanks for the reply.  I am in fact converting to "RGB"
> first... at least I think so.  Here's the code I'm using that produces
> bad results:
>
> from PIL import Image
>
> # io is a file handle
> pil_image = Image.open(io)
>
> # convert to rgb
> pil_image = pil_image.convert('RGB')
>
> # new_width/new_height are calculated to retain the
> # current height/width proportions
> new_size = (new_width, new_height)
>
> #resize the image
> pil_image = pil_image.resize(new_size, Image.ANTIALIAS)
>
> # save the image back to disk
> pil_image.save(io, 'GIF')

is the grain you're talking about perhaps floyd-steinberg dithering?  do
your images look better if you insert

    pil_image = pil_image.convert("P", dither=Image.NONE)

before you save the image?

</F>

_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Andy McCurdy-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Your suggestion didn't seem to fix the problem.  It will probably be
helpful for you to take a look at what I'm seeing.

Here's the original .gif file I'm testing with:
http://www.andymccurdy.com/original.gif

Here's the resized gif with the original code I pasted.  You'll see a
bunch of 'dots' throughout the image:
http://www.andymccurdy.com/resized_1.gif

Here's the image resized again with your suggestion of converting to
"P" mode and setting the dithering prior to saving:
http://www.andymccurdy.com/resized_2.gif

You'll see both of the resized images are pretty poor quality.

On Jan 9, 2008 1:13 PM, Fredrik Lundh <fredrik@...> wrote:

> Andy McCurdy wrote:
>
> > Fredrik, thanks for the reply.  I am in fact converting to "RGB"
> > first... at least I think so.  Here's the code I'm using that produces
> > bad results:
> >
> > from PIL import Image
> >
> > # io is a file handle
> > pil_image = Image.open(io)
> >
> > # convert to rgb
> > pil_image = pil_image.convert('RGB')
> >
> > # new_width/new_height are calculated to retain the
> > # current height/width proportions
> > new_size = (new_width, new_height)
> >
> > #resize the image
> > pil_image = pil_image.resize(new_size, Image.ANTIALIAS)
> >
> > # save the image back to disk
> > pil_image.save(io, 'GIF')
>
> is the grain you're talking about perhaps floyd-steinberg dithering?  do
> your images look better if you insert
>
>     pil_image = pil_image.convert("P", dither=Image.NONE)
>
> before you save the image?
>
>
> </F>
>
> _______________________________________________
> Image-SIG maillist  -  Image-SIG@...
> http://mail.python.org/mailman/listinfo/image-sig
>
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Douglas Bagnall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

hi Andy

> Here's the resized gif with the original code I pasted.  You'll see a
> bunch of 'dots' throughout the image:
> http://www.andymccurdy.com/resized_1.gif

PIL uses the so-called "web palette" by default.  Your image uses
#fdfdfd for white, but the web palette uses #ffffff. So it dithers to
approximate #fdfdfd.  You probably really want the background to be
pure #ffffff white, because printers etc will also dither, but the
more immediate problem is the web palette. Try this:

pil_image = pil_image.convert("P", palette=Image.ADAPTIVE)

or

pil_image = pil_image.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE)

These options are not well documented, but you can find them in the
PIL/Image.py source.

douglas
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Andy McCurdy-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Douglas,

I interpreted your response as a setting to change to make this
specific image resize better.  I'm using PIL to resize images that
users upload to my website.  Since I don't have control over the
media, I need generic settings that will be good for all users.  What
settings would you suggest to be best for all images, not just the
example I provided?

On Jan 9, 2008 2:57 PM, douglas bagnall <douglas@...> wrote:

> hi Andy
>
> > Here's the resized gif with the original code I pasted.  You'll see a
> > bunch of 'dots' throughout the image:
> > http://www.andymccurdy.com/resized_1.gif
>
> PIL uses the so-called "web palette" by default.  Your image uses
> #fdfdfd for white, but the web palette uses #ffffff. So it dithers to
> approximate #fdfdfd.  You probably really want the background to be
> pure #ffffff white, because printers etc will also dither, but the
> more immediate problem is the web palette. Try this:
>
> pil_image = pil_image.convert("P", palette=Image.ADAPTIVE)
>
> or
>
> pil_image = pil_image.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE)
>
> These options are not well documented, but you can find them in the
> PIL/Image.py source.
>
> douglas
>
> _______________________________________________
> Image-SIG maillist  -  Image-SIG@...
> http://mail.python.org/mailman/listinfo/image-sig
>
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Douglas Bagnall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andy McCurdy <andy@...> wrote:

> I interpreted your response as a setting to change to make this
> specific image resize better.  I'm using PIL to resize images that
> users upload to my website.  Since I don't have control over the
> media, I need generic settings that will be good for all users.  What
> settings would you suggest to be best for all images, not just the
> example I provided?

Using palette=Image.ADAPTIVE will be better for all images unless the
images are already in the web palette, or the viewers are from 1995
and have 256 colour displays.  Both of these are unlikely, and in any
case the adaptive system will work well enough for them. It will be
slower though.

douglas
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Andy McCurdy-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Douglas.  Just tested it out, and the quality has improved
dramatically on all GIF images I threw at it.

On Jan 9, 2008 3:34 PM, douglas bagnall <douglas@...> wrote:

> Andy McCurdy <andy@...> wrote:
>
> > I interpreted your response as a setting to change to make this
> > specific image resize better.  I'm using PIL to resize images that
> > users upload to my website.  Since I don't have control over the
> > media, I need generic settings that will be good for all users.  What
> > settings would you suggest to be best for all images, not just the
> > example I provided?
>
> Using palette=Image.ADAPTIVE will be better for all images unless the
> images are already in the web palette, or the viewers are from 1995
> and have 256 colour displays.  Both of these are unlikely, and in any
> case the adaptive system will work well enough for them. It will be
> slower though.
>
> douglas
>
_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Fredrik Lundh :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andy McCurdy wrote:

>> Using palette=Image.ADAPTIVE will be better for all images unless the
>> images are already in the web palette, or the viewers are from 1995
>> and have 256 colour displays.  Both of these are unlikely, and in any
>> case the adaptive system will work well enough for them. It will be
>> slower though.
 >
 > Thanks Douglas.  Just tested it out, and the quality has improved
 > dramatically on all GIF images I threw at it.

In addition to Douglas' excellent advice, you should probably also ask
yourself if you really need to store the thumbnails as GIF images.

For the general case, I'd probably use JPEG for everything (if it's good
enough for Google, etc).  If you have lots of non-photographic images in
your database, you can use PNG for things that have 256 colors or less:

     if im.getcolors(256):
         # limited number of colors
         im = im.convert("P", palette=Image.ADAPTIVE, dither=Image.NONE)
         im.save(out, "PNG")
     else:
         im.save(out, "JPEG")

(getcolors returns None if there are more than the given number of
colors in the image.  you can change 256 to something larger if you want
to; 512 or 1024 probably works well in practice)

</F>

_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig

Re: Poor Image Quality When Resizing a GIF

by Scott David Daniels :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fredrik Lundh wrote:
> For the general case, I'd probably use JPEG for everything (if it's good
> enough for Google, etc).  If you have lots of non-photographic images in
> your database, you can use PNG for things that have 256 colors or less:
>      if im.getcolors(256):
>          # limited number of colors
>          im = im.convert("P", palette=Image.ADAPTIVE, dither=Image.NONE)
>          im.save(out, "PNG")
>      else:
>          im.save(out, "JPEG")
PNG can cope with any number of colors (one of its advantages over GIF).
I suspect your advice is to determine the photo/non-photo property
by looking at the number of distinct colors.  Unfortunately, the naive
reader might infer that he couldn't put 300-color images in PNG.

--Scott David Daniels
Scott.Daniels@...

_______________________________________________
Image-SIG maillist  -  Image-SIG@...
http://mail.python.org/mailman/listinfo/image-sig