Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload thumbnails are blurry #1942

Closed
miketaylr opened this issue Nov 28, 2017 · 8 comments
Closed

Upload thumbnails are blurry #1942

miketaylr opened this issue Nov 28, 2017 · 8 comments

Comments

@miketaylr
Copy link
Member

Not sure if we can tune the jpeg compression a bit -- I find the thumbnail image to be a little too blurry.

https://staging.webcompat.com/issues/1308 as an example.

@miketaylr
Copy link
Member Author

@karlcow what do you think?

@karlcow
Copy link
Member

karlcow commented Nov 29, 2017

houla THAT is blurry. :)
Yup. we can probably tune or find a new way of doing it. The issue is time it takes for generating better quality.

Some options:

  1. tweak the values to find a better sweet spots for compression/quality/time.
  2. OR create a out of the band mechanism server side, which queue a post-processing. What I mean here the blurry image is here at first but then on the server side we use a script to regenerate a better quality image from the original we have and save it as the new thumbnail. Users are not being delayed. And we can provide more sophisticated things ala macOS imageOptim https://imageoptim.com/mac or https://imageoptim.com/versions.html

I guess we worked out the quality in #1267

@karlcow
Copy link
Member

karlcow commented Nov 29, 2017

ah no #710 is where we tested the quality/time.

@karlcow
Copy link
Member

karlcow commented Nov 29, 2017

that would be a very cool 2018Q1 goal if we were going the out of band version.

Option 1. We can try to improve a bit more the parameters. I need to do more tests. Probably 1 day of work testing options.

@karlcow
Copy link
Member

karlcow commented Aug 9, 2018

We are using Pillow 4.0.0

@karlcow
Copy link
Member

karlcow commented Aug 9, 2018

let me try this image https://staging.webcompat.com/issues/1308 again locally.

Original image
original-test

Original thumbnail
original-thumbnail

Running on

commit 42781cc3a673b622b9fd0d5b07f6250895160a4b
Author: Mike Taylor <miketaylr@gmail.com>
Date:   Thu Aug 2 18:04:01 2018 -0500

    v12.2.0 changelog update

12.2.0 version

  • macos 10.13.6 (17G65)
  • /usr/local/lib/libjpeg.8.dylib (compatibility version 13.0.0, current version 13.0.0)

The quality is indeed bad.
12 2 0-thumbnail

Upgrading to pillow 5.2.0

→ pip install -r config/requirements.txt 
Requirement already satisfied: blinker==1.4 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 1)) (1.4)
Requirement already satisfied: Flask==1.0.2 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 2)) (1.0.2)
Requirement already satisfied: Flask-Limiter==0.9.3 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 3)) (0.9.3)
Requirement already satisfied: Flask-SQLAlchemy==2.1 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 4)) (2.1)
Requirement already satisfied: Flask-WTF==0.14.2 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 5)) (0.14.2)
Requirement already satisfied: GitHub-Flask==3.1.5 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 6)) (3.1.5)
Requirement already satisfied: mock==2.0.0 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 7)) (2.0.0)
Requirement already satisfied: nose==1.3.7 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 8)) (1.3.7)
Requirement already satisfied: pep8==1.7.0 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 9)) (1.7.0)
Collecting Pillow==5.2.0 (from -r config/requirements.txt (line 10))
  Downloading https://files.pythonhosted.org/packages/a8/56/0f2427d8df966e002fbb748d8537d8f037321b762997a6f05d24cb7334d7/Pillow-5.2.0-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (3.6MB)
    100% |████████████████████████████████| 3.6MB 3.5MB/s 
Requirement already satisfied: requests==2.13.0 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 11)) (2.13.0)
Requirement already satisfied: ua-parser==0.8 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 12)) (0.8.0)
Requirement already satisfied: WTForms==2.1 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from -r config/requirements.txt (line 13)) (2.1)
Requirement already satisfied: Jinja2>=2.10 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask==1.0.2->-r config/requirements.txt (line 2)) (2.10)
Requirement already satisfied: itsdangerous>=0.24 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask==1.0.2->-r config/requirements.txt (line 2)) (0.24)
Requirement already satisfied: Werkzeug>=0.14 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask==1.0.2->-r config/requirements.txt (line 2)) (0.14.1)
Requirement already satisfied: click>=5.1 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask==1.0.2->-r config/requirements.txt (line 2)) (6.7)
Requirement already satisfied: limits in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask-Limiter==0.9.3->-r config/requirements.txt (line 3)) (1.3)
Requirement already satisfied: six>=1.4.1 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask-Limiter==0.9.3->-r config/requirements.txt (line 3)) (1.11.0)
Requirement already satisfied: SQLAlchemy>=0.7 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Flask-SQLAlchemy==2.1->-r config/requirements.txt (line 4)) (1.2.6)
Requirement already satisfied: pbr>=0.11 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from mock==2.0.0->-r config/requirements.txt (line 7)) (4.0.2)
Requirement already satisfied: funcsigs>=1; python_version < "3.3" in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from mock==2.0.0->-r config/requirements.txt (line 7)) (1.0.2)
Requirement already satisfied: MarkupSafe>=0.23 in /Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages (from Jinja2>=2.10->Flask==1.0.2->-r config/requirements.txt (line 2)) (1.0)
Installing collected packages: Pillow
  Found existing installation: Pillow 4.0.0
    Uninstalling Pillow-4.0.0:
      Successfully uninstalled Pillow-4.0.0
Successfully installed Pillow-5.2.0
You are using pip version 10.0.1, however version 18.0 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

And redoing a upload test. It didn't change anything.

pillow-5 2 0-thumbnail

And the sizes are identical

-rw-rw-rw-@ 1 karl  staff  203526  9 aoû 12:30 original-test.jpg
-rw-rw-rw-@ 1 karl  staff   24233  9 aoû 12:30 original-thumbnail.jpg
-rw-rw-rw-@ 1 karl  staff   24142  9 aoû 12:36 12.2.0-thumbnail.jpeg
-rw-rw-rw-@ 1 karl  staff   24142  9 aoû 13:08 pillow-5.2.0-thumbnail.jpeg

Maybe we can tweak a bit the quality parameters.

Dropping the optimize + 5.2.0

if self.image_object.format in ['JPEG', 'JPG', 'JPE', 'PNG']:
save_parameters['optimize'] = True

  • Image.save
  • JPEG parameters
    If present and true, indicates that the encoder should make an extra pass over the image in order to select optimal encoder settings.
    

Quality didn't improve. Image is bigger.

-rw-rw-rw-@ 1 karl  staff  203526  9 aoû 12:30 original-test.jpg
-rw-rw-rw-@ 1 karl  staff   24233  9 aoû 12:30 original-thumbnail.jpg
-rw-rw-rw-@ 1 karl  staff   24142  9 aoû 12:36 12.2.0-thumbnail.jpeg
-rw-rw-rw-@ 1 karl  staff   24142  9 aoû 13:08 pillow-5.2.0-thumbnail.jpeg
-rw-rw-rw-@ 1 karl  staff   26808  9 aoû 13:20 pillow-5.2.0-no-optimize-thumbnail.jpeg

pillow-5 2 0-no-optimize-thumbnail

Let's put optimize back.

tweaking the thumbnail quality parameter

self.image_object.thumbnail(size, Image.BILINEAR)

Check the previous discussions about the quality parameters

Trying to re-run the tests from 2 years ago

→ python resize-filter.py 
Traceback (most recent call last):
  File "resize-filter.py", line 22, in <module>
    original2.save(thumb_name, 'JPEG')
  File "/Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages/PIL/Image.py", line 1950, in save
    save_handler(self, fp, filename)
  File "/Users/karl/.virtualenvs/webcompatcom/lib/python2.7/site-packages/PIL/JpegImagePlugin.py", line 623, in _save
    raise IOError("cannot write mode %s as JPEG" % im.mode)
IOError: cannot write mode RGBA as JPEG

Interesting 🤔

Ah! Deprecated

Before Pillow 4.2.0, attempting to save an RGBA image as JPEG would discard the alpha channel. From Pillow 3.4.0, a deprecation warning was shown. From Pillow 4.2.0, the deprecation warning is removed and an :py:exc:IOError is raised.

I need to convert the image to RGB first. Probably something to add to our code too (for people uploading PNG image with an alpha channel), if we do not want to have bad surprises when switching to Pillow 5.2.0

new resize-filter script.

Things have improved a lot in terms of time. But new computer too… so we can't directly compare with the previous results. The convert to RGB adds only a minimal penalty, so we are safe for this.

This is testing the previous japantimes PNG image.

    thumb_nearest.jpg:
        creating thumbnail 0.0048 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0196 seconds
        ---------------------------------------------
        total = 0.0246 seconds
    

    thumb_bilinear.jpg:
        creating thumbnail 0.0118 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0079 seconds
        ---------------------------------------------
        total = 0.0199 seconds
    

    thumb_bicubic.jpg:
        creating thumbnail 0.0162 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0075 seconds
        ---------------------------------------------
        total = 0.0239 seconds
    

    thumb_lanczos.jpg:
        creating thumbnail 0.0214 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.008 seconds
        ---------------------------------------------
        total = 0.0296 seconds
    

    thumb_antialias.jpg:
        creating thumbnail 0.0223 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0075 seconds
        ---------------------------------------------
        total = 0.03 seconds

Let's try to test with @miketaylr image and resized at 700, 700 as on webcompat.

-rw-r--r--  1 karl  staff   29375  9 aoû 14:13 thumb_antialias.jpg
-rw-r--r--  1 karl  staff   28440  9 aoû 14:13 thumb_bicubic.jpg
-rw-r--r--  1 karl  staff   26808  9 aoû 14:13 thumb_bilinear.jpg
-rw-r--r--  1 karl  staff   29375  9 aoû 14:13 thumb_lanczos.jpg
-rw-r--r--  1 karl  staff   32410  9 aoû 14:13 thumb_nearest.jpg

and

    thumb_nearest.jpg:
        creating thumbnail 0.0021 seconds
        convert to RGB     0.0007 seconds
        save thumbnail     0.0117 seconds
        ---------------------------------------------
        total = 0.0145 seconds
    

    thumb_bilinear.jpg:
        creating thumbnail 0.0272 seconds
        convert to RGB     0.0001 seconds
        save thumbnail     0.0118 seconds
        ---------------------------------------------
        total = 0.0391 seconds
    

    thumb_bicubic.jpg:
        creating thumbnail 0.0438 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0119 seconds
        ---------------------------------------------
        total = 0.0559 seconds
    

    thumb_lanczos.jpg:
        creating thumbnail 0.0626 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0125 seconds
        ---------------------------------------------
        total = 0.0753 seconds
    

    thumb_antialias.jpg:
        creating thumbnail 0.0636 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0115 seconds
        ---------------------------------------------
        total = 0.0753 seconds

Nearest is still the crappiest. The two best ones are: antialias and lanczos

antialias:

thumb_antialias

lanczos

thumb_lanczos

Image size let see with 1024px instead of 700px

-rw-r--r--  1 karl  staff   50904  9 aoû 14:22 thumb_antialias.jpg
-rw-r--r--  1 karl  staff   49667  9 aoû 14:22 thumb_bicubic.jpg
-rw-r--r--  1 karl  staff   47195  9 aoû 14:22 thumb_bilinear.jpg
-rw-r--r--  1 karl  staff   50904  9 aoû 14:22 thumb_lanczos.jpg
-rw-r--r--  1 karl  staff   53802  9 aoû 14:22 thumb_nearest.jpg


    thumb_nearest.jpg:
        creating thumbnail 0.003 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0242 seconds
        ---------------------------------------------
        total = 0.0274 seconds
    

    thumb_bilinear.jpg:
        creating thumbnail 0.0333 seconds
        convert to RGB     0.0005 seconds
        save thumbnail     0.0241 seconds
        ---------------------------------------------
        total = 0.0578 seconds
    

    thumb_bicubic.jpg:
        creating thumbnail 0.0672 seconds
        convert to RGB     0.0003 seconds
        save thumbnail     0.0231 seconds
        ---------------------------------------------
        total = 0.0906 seconds
    

    thumb_lanczos.jpg:
        creating thumbnail 0.0984 seconds
        convert to RGB     0.0003 seconds
        save thumbnail     0.0249 seconds
        ---------------------------------------------
        total = 0.1235 seconds
    

    thumb_antialias.jpg:
        creating thumbnail 0.0782 seconds
        convert to RGB     0.0003 seconds
        save thumbnail     0.0245 seconds
        ---------------------------------------------
        total = 0.103 seconds

Quality

Bilinear
thumb_bilinear

Antialias
thumb_antialias

Lanczos
thumb_lanczos

The original image provided by mike is not heavy. I think I need to test with a very heavy image too.

Heavy image (2.3M)

-rw-r--r--@  1 karl  staff  2428979  9 aoû 14:32 tokyo-map.png
-rw-r--r--   1 karl  staff   152956  9 aoû 14:34 thumb_antialias.jpg
-rw-r--r--   1 karl  staff   146880  9 aoû 14:34 thumb_bicubic.jpg
-rw-r--r--   1 karl  staff   134872  9 aoû 14:34 thumb_bilinear.jpg
-rw-r--r--   1 karl  staff   152956  9 aoû 14:34 thumb_lanczos.jpg
-rw-r--r--   1 karl  staff   179750  9 aoû 14:34 thumb_nearest.jpg

    thumb_nearest.jpg:
        creating thumbnail 0.0132 seconds
        convert to RGB     0.0008 seconds
        save thumbnail     0.0518 seconds
        ---------------------------------------------
        total = 0.0659 seconds
    

    thumb_bilinear.jpg:
        creating thumbnail 0.0303 seconds
        convert to RGB     0.0009 seconds
        save thumbnail     0.0341 seconds
        ---------------------------------------------
        total = 0.0654 seconds
    

    thumb_bicubic.jpg:
        creating thumbnail 0.0489 seconds
        convert to RGB     0.0009 seconds
        save thumbnail     0.0359 seconds
        ---------------------------------------------
        total = 0.0856 seconds
    

    thumb_lanczos.jpg:
        creating thumbnail 0.0627 seconds
        convert to RGB     0.0009 seconds
        save thumbnail     0.0351 seconds
        ---------------------------------------------
        total = 0.0986 seconds
    

    thumb_antialias.jpg:
        creating thumbnail 0.0628 seconds
        convert to RGB     0.0009 seconds
        save thumbnail     0.035 seconds
        ---------------------------------------------
        total = 0.0987 seconds

This is not too bad.

TO EXPLORE

@karlcow
Copy link
Member

karlcow commented Aug 9, 2018

Any take on this? Any feelings 😝 @miketaylr

The doc contains a table for performance-quality comparison

Maybe HAMMING is worth trying. Let's try a test with this.

700

-rw-r--r--   1 karl  staff    26808  9 aoû 15:05 thumb_bilinear.jpg
-rw-r--r--   1 karl  staff    28623  9 aoû 15:05 thumb_hamming.jpg

    thumb_bilinear.jpg:
        creating thumbnail 0.0275 seconds
        convert to RGB     0.0001 seconds
        save thumbnail     0.0117 seconds
        ---------------------------------------------
        total = 0.0394 seconds
    

    thumb_hamming.jpg:
        creating thumbnail 0.0271 seconds
        convert to RGB     0.0002 seconds
        save thumbnail     0.0121 seconds
        ---------------------------------------------
        total = 0.0394 seconds

bilinear (700, 700)
thumb_bilinear

hamming (700, 700)

thumb_hamming

1024

-rw-r--r--   1 karl  staff    47195  9 aoû 15:02 thumb_bilinear.jpg
-rw-r--r--   1 karl  staff    48900  9 aoû 15:02 thumb_hamming.jpg

    thumb_bilinear.jpg:
        creating thumbnail 0.0332 seconds
        convert to RGB     0.0004 seconds
        save thumbnail     0.0235 seconds
        ---------------------------------------------
        total = 0.0571 seconds
    

    thumb_hamming.jpg:
        creating thumbnail 0.0307 seconds
        convert to RGB     0.0003 seconds
        save thumbnail     0.0248 seconds
        ---------------------------------------------
        total = 0.0558 seconds

bilinear (1024, 1024)
thumb_bilinear

hamming (1024, 1024)

thumb_hamming

karlcow added a commit to karlcow/webcompat.com that referenced this issue Aug 9, 2018
karlcow added a commit to karlcow/webcompat.com that referenced this issue Aug 9, 2018
karlcow added a commit to karlcow/webcompat.com that referenced this issue Aug 9, 2018
karlcow added a commit to karlcow/webcompat.com that referenced this issue Aug 9, 2018
@miketaylr
Copy link
Member Author

HAMMING looks pretty good!

🐖

@karlcow karlcow closed this as completed in 2223a93 Aug 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants