Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using ImageMagick to resize your Images [FSTO]

newtron
April 08, 2015

Using ImageMagick to resize your Images [FSTO]

Full Stack Toronto,
2015-04-08
https://github.com/nwtn/pres-imagemagick-fsto

newtron

April 08, 2015
Tweet

More Decks by newtron

Other Decks in Technology

Transcript

  1. David Newton, St. Michael’s Hospital
    1
    1
    Using ImageMagick to resize your Images
    Full Stack Toronto, 2015-04-08
    Twitter: @newtron
    Github: @nwtn
    Email: [email protected]
    Slides + image credits:
    https://github.com/nwtn/pres-imagemagick-fsto

    View full-size slide

  2. 3
    Responsive images
    are a pain in the butt

    View full-size slide

  3. 7
    ImageMagick, y’all

    View full-size slide

  4. 9
    $ brew install imagemagick

    View full-size slide

  5. 10
    Condition (unoptimized input) File size: mean File size: % difference
    Photoshop CC, with optimization 260,305 bytes
    ImageMagick `-resize` 385,795 bytes 48.21%

    View full-size slide

  6. 11
    How does
    image resizing work?

    View full-size slide

  7. 12
    685,936 pixels 189,739 pixels

    View full-size slide

  8. 13
    …to 64 pixels?
    How do we get from 16 pixels…

    View full-size slide

  9. 14
    != resampling

    View full-size slide

  10. 15
    …to 64 pixels?
    How do we get from 16 pixels…

    View full-size slide

  11. 16
    …to 64 pixels?
    How do we get from 16 pixels…
    Background interpolation

    View full-size slide

  12. 17
    …to 64 pixels?
    How do we get from 16 pixels…
    Nearest-neighbour interpolation

    View full-size slide

  13. 18
    Nearest-neighbour interpolation

    View full-size slide

  14. 19
    Bicubic interpolation

    View full-size slide

  15. 20
    Nearest-neighbour vs. bicubic interpolation

    View full-size slide

  16. 21
    7 colours 1,146 colours

    View full-size slide

  17. More colours =
    More bytes*
    23

    View full-size slide

  18. 24
    https://github.com/nwtn/image-resize-tests/

    View full-size slide

  19. 25
    How do we know
    which options are best?

    View full-size slide

  20. Quality
    objective: measured with DSSIM
    26

    View full-size slide

  21. 27
    Control Test
    Difference

    View full-size slide

  22. Quality
    subjective: from me
    29

    View full-size slide

  23. Test a variety of images
    30

    View full-size slide

  24. 31
    The best* settings for
    ImageMagick

    View full-size slide

  25. 32
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.08+8.3+0.045 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB
    INPUT_PATH
    With optimization:

    View full-size slide

  26. 33
    https://github.com/toy/image_optim
    https://github.com/ajslater/picopt
    https://imageoptim.com/

    View full-size slide

  27. 34
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH
    Without optimization:

    View full-size slide

  28. 35
    mogrify vs. convert

    View full-size slide

  29. 37
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  30. 38
    resampling filter

    View full-size slide

  31. 39
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  32. 40
    Adaptive resize Distort resize Geometry Interpolative resize
    Liquid rescale Resize Sample Scale
    Thumbnail

    View full-size slide

  33. 41
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  34. 44
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  35. 46
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  36. 48
    sharpening

    View full-size slide

  37. 49
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  38. 50
    -unsharp 0.25x0.25+8+0.045
    radius sigma gain threshold

    View full-size slide

  39. 51
    -unsharp 0.25x0.25+8+0.045
    radius sigma gain threshold

    View full-size slide

  40. 52
    colour reduction

    View full-size slide

  41. 53
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  42. 59
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -colors
    NUMBER_OF_COLORS -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH
    If output file size is larger than input:

    View full-size slide

  43. 60
    7 colours 1,146 colours

    View full-size slide

  44. 61
    7 colours 7 colours

    View full-size slide

  45. 62
    quality and compression

    View full-size slide

  46. 63
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  47. 64
    quality 10 quality 40
    quality 70 quality 100

    View full-size slide

  48. 65
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  49. 67
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  50. 68
    progressive rendering

    View full-size slide

  51. 69
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  52. Progressive JPEGs
    Good? Evil?
    72

    View full-size slide

  53. 73
    colour space

    View full-size slide

  54. 74
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH

    View full-size slide

  55. 76
    The best* settings for
    ImageMagick

    View full-size slide

  56. 77
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.08+8.3+0.045 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB
    INPUT_PATH
    With optimization:

    View full-size slide

  57. 78
    mogrify -path OUTPUT_PATH -filter Triangle -
    define filter:support=2.0 -thumbnail OUTPUT_WIDTH
    -unsharp 0.25x0.25+8+0.065 -dither None -
    posterize 136 -quality 82 -define jpeg:fancy-
    upsampling=off -define png:compression-filter=5 -
    define png:compression-level=9 -define
    png:compression-strategy=1 -define png:exclude-
    chunk=all -interlace none -colorspace sRGB -strip
    INPUT_PATH
    Without optimization:

    View full-size slide

  58. 79
    Why even bother?

    View full-size slide

  59. 80
    Condition (unoptimized input) File size: mean File size: % difference
    My settings, optimization 218,274 bytes
    My settings, no optimization 259,852 bytes 19.05%

    View full-size slide

  60. 81
    Condition (unoptimized input) File size: mean File size: % difference
    My settings, optimization 218,274 bytes
    My settings, no optimization 259,852 bytes 19.05%
    Photoshop CC, optimization 260,305 bytes 19.28%
    Photoshop CC, no optimization 299,710 bytes 35.26%

    View full-size slide

  61. 82
    Condition (unoptimized input) File size: mean File size: % difference
    My settings, optimization 218,274 bytes
    My settings, no optimization 259,852 bytes 19.05%
    Photoshop CC, optimization 260,305 bytes 19.28%
    Photoshop CC, no optimization 299,710 bytes 35.26%
    basic `-resize` / WordPress* 385,795 bytes 76.75%

    View full-size slide

  62. 83
    Condition (unoptimized input) File size: mean File size: % difference
    My settings, optimization 218,274 bytes
    My settings, no optimization 259,852 bytes 19.05%
    Photoshop CC, optimization 260,305 bytes 19.28%
    Photoshop CC, no optimization 299,710 bytes 35.26%
    CodeIgniter / ExpressionEngine 340,461 bytes 55.98%
    TYPO3.CMS* 359,112 bytes 64.52%
    basic `-resize` / WordPress* 385,795 bytes 76.75%
    Drupal* 397,588 bytes 82.15%
    Perch* 416,790 bytes 90.95%
    Craft CMS* 425,259 bytes 94.83%
    grunt-responsive-images* 500,273 bytes 129.20%

    View full-size slide

  63. 84
    PHP Imagick

    View full-size slide

  64. 87
    CLI Imagick DSSIM File Size
    -filter N/A N/A N/A
    -define filter:support setOption() ? ?
    -thumbnail thumbnailImage() ✗ ✗
    -unsharp unsharpMaskImage() ✔ ✔
    -dither & -posterize posterizeImage() ✔ ✔
    -quality setImageCompressionQuality() ✔ ✗
    -define jpeg:fancy-upsampling setOption() ✔ ✔
    -define png:compression-filter setOption() ✔ ✔
    -define png:compression-level setOption() ✔ ✔
    -define png:compression-strategy setOption() ✔ ✔
    -define png:exclude-chunk setOption() ✔ ✔
    -interlace setInterlaceScheme() ✔ ✔
    -colorspace setColorspace() ✔ ✔
    -strip stripImage() ✔ ✔

    View full-size slide

  65. 89
    CLI Imagick DSSIM File Size
    -filter custom ✔ ✗
    -define filter:support setOption() ✔ ✗
    -thumbnail custom ✔ ✗
    -unsharp unsharpMaskImage() ✔ ✔
    -dither & -posterize posterizeImage() ✔ ✔
    -quality setImageCompressionQuality() ✔ ✔
    -define jpeg:fancy-upsampling setOption() ✔ ✔
    -define png:compression-filter setOption() ✔ ✔
    -define png:compression-level setOption() ✔ ✔
    -define png:compression-strategy setOption() ✔ ✔
    -define png:exclude-chunk setOption() ✔ ✔
    -interlace setInterlaceScheme() ✔ ✔
    -colorspace setColorspace() ✔ ✔
    -strip stripImage() ✔ ✔

    View full-size slide

  66. 90
    OK…
    but it’s still a pain in the butt

    View full-size slide

  67. 91
    https://github.com/nwtn/php-respimg/
    Resizing with smart defaults
    + more coming soon?

    View full-size slide

  68. 92
    $ composer require nwtn/php-respimg

    View full-size slide

  69. 94
    https://www.npmjs.com/package/grunt-respimg
    Resizing with smart defaults
    SVG to PNG rasterization
    Optimization

    View full-size slide

  70. 95
    $ npm install grunt-respimg --save-dev

    View full-size slide

  71. David Newton, St. Michael’s Hospital
    98
    Using ImageMagick to resize your Images
    Full Stack Toronto, 2015-04-08
    Twitter: @newtron
    Github: @nwtn
    Email: [email protected]
    Slides + image credits:
    https://github.com/nwtn/pres-imagemagick-fsto

    View full-size slide