Using ImageMagick to resize your Images [GTA PHP]

C3e8ba214714b1402f3073334249fcdc?s=47 newtron
April 07, 2015

Using ImageMagick to resize your Images [GTA PHP]

GTA PHP User Group,
2015-04-07
https://github.com/nwtn/pres-imagemagick-gtaphp

C3e8ba214714b1402f3073334249fcdc?s=128

newtron

April 07, 2015
Tweet

Transcript

  1. David Newton, St. Michael’s Hospital 1 1 Using ImageMagick to

    resize your Images GTA PHP User Group, 2015-04-07 Twitter: @newtron Github: @nwtn Email: david@davidnewton.ca Slides + image credits: https://github.com/nwtn/pres-imagemagick-gtaphp
  2. 2

  3. 3 Responsive images are a pain in the butt

  4. 4

  5. 5

  6. 6

  7. 7 ImageMagick, y’all

  8. 8

  9. 9 $ brew install imagemagick

  10. 10 $ brew install php56-imagick

  11. 11 $ apt-get install php-imagick

  12. 12 Condition (unoptimized input) File size: mean File size: %

    difference Photoshop CC, with optimization 260,305 bytes ImageMagick `-resize` 385,795 bytes 48.21%
  13. 13 How does image resizing work?

  14. 14 685,936 pixels 189,739 pixels

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

    pixels…
  16. 16 != resampling

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

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

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

    pixels… Nearest-neighbour interpolation
  20. 20 Nearest-neighbour interpolation

  21. 21 Bicubic interpolation

  22. 22 Nearest-neighbour vs. bicubic interpolation

  23. 23 7 colours 1,146 colours

  24. 24

  25. More colours = More bytes* 25

  26. 26 https://github.com/nwtn/image-resize-tests/

  27. 27 How do we know which options are best?

  28. Quality objective: measured with DSSIM 28

  29. 29 Control Test Difference

  30. 30

  31. Quality subjective: from me 31

  32. Test a variety of images 32

  33. 33 The best* settings for ImageMagick

  34. 34 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:
  35. 35 https://github.com/toy/image_optim https://github.com/ajslater/picopt https://imageoptim.com/

  36. 36 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:
  37. 37 mogrify vs. convert

  38. 38

  39. 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
  40. 40 resampling filter

  41. 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
  42. 42 Adaptive resize Distort resize Geometry Interpolative resize Liquid rescale

    Resize Sample Scale Thumbnail
  43. 43 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
  44. 44

  45. 45

  46. 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
  47. 47

  48. 48 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
  49. 49 Fancy

  50. 50 sharpening

  51. 51 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
  52. 52 -unsharp 0.25x0.25+8+0.045 radius sigma gain threshold

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

  54. 54 colour reduction

  55. 55 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
  56. 56

  57. 57

  58. 58

  59. 59

  60. 60

  61. 61 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:
  62. 62 7 colours 1,146 colours

  63. 63 7 colours 7 colours

  64. 64 quality and compression

  65. 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
  66. 66 quality 10 quality 40 quality 70 quality 100

  67. 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
  68. 68 metadata

  69. 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
  70. 70 progressive rendering

  71. 71 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
  72. 72

  73. 73

  74. Progressive JPEGs Good? Evil? 74

  75. 75 colour space

  76. 76 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
  77. 77

  78. 78 The best* settings for ImageMagick

  79. 79 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:
  80. 80 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:
  81. 81 Why even bother?

  82. 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%
  83. 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%
  84. 84 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%
  85. 85 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%
  86. 86 PHP Imagick

  87. 87

  88. 88

  89. 89 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() ✔ ✔
  90. 90

  91. 91 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() ✔ ✔
  92. 92 OK… but it’s still a pain in the butt

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

  94. 94

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

    Optimization
  96. 96 $ npm install grunt-respimg --save-dev

  97. 97

  98. 98

  99. David Newton, St. Michael’s Hospital 99 Using ImageMagick to resize

    your Images GTA PHP User Group, 2015-04-07 Twitter: @newtron Github: @nwtn Email: david@davidnewton.ca Slides + image credits: https://github.com/nwtn/pres-imagemagick-gtaphp