Introduction to Imagine

43,779 views

Published on

Image processing in PHP is hard, but now we have Imagine, inspired by Python PIL, made for PHP 5.3, this image manipulation library will meet all your needs

Published in: Technology, Art & Photos
5 Comments
37 Likes
Statistics
Notes
No Downloads
Views
Total views
43,779
On SlideShare
0
From Embeds
0
Number of Embeds
2,723
Actions
Shares
0
Downloads
234
Comments
5
Likes
37
Embeds 0
No embeds

No notes for slide

Introduction to Imagine

  1. 1. Introduction to Imagine image processing for PHP 5.3+ http://goo.gl/T994G
  2. 2. Image processing in PHP is hard
  3. 3. Existing tools• GD• Imagick (ImageMagick extension)• Gmagick (GraphicsMagick extension)• Cairo
  4. 4. $width = //target width$height = //target height$src = imagecreatefrompng(/path/to/image.png);$dest = imagecreatetruecolor($width, $height);imagealphablending($dest, false);imagesavealpha($dest, true);imagecopyresampled($dest, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));imagepng($dest,/path/to/resized/image.png); Resize in GD
  5. 5. $width = //target width$height = //target height$image = new Imagick(/path/to/image.png);$image->adaptiveResizeImage($width, $height);$image->writeImage(/path/to/resized/image.png); Resize in Imagick
  6. 6. Existing tools• not testable• inconsistent• cluttered apis• not intuitive
  7. 7. Existing tools don’t cut it
  8. 8. Imagine...• all drivers implemented the same interfaces• you could write code once, use with many drivers• there were interfaces for mocking in tests• API was simple and intuitive
  9. 9. Imagine for PHP 5.3+ stop imagining, its all there
  10. 10. Imagine for PHP 5.3+ Inspired by Python’s PIL http://www.pythonware.com/products/pil/
  11. 11. $width = //target width $height = //target height $imagine = new ImagineGdImagine(); $imagine->open(/path/to/image.png) ->resize(new ImagineBox($width, $height)) ->save(/path/to/resized/image.png);Resize in Imagine (GD)
  12. 12. $width = //target width $height = //target height $imagine = new ImagineImagickImagine(); $imagine->open(/path/to/image.png) ->resize(new ImagineBox($width, $height)) ->save(/path/to/resized/image.png);Resize in Imagine (Imagick)
  13. 13. Consistency1. identify low level operations2. split them into logical groups3. provide implementation for each driver
  14. 14. Operations• resize • ellipse• rotate • polygon• crop • line• save • dot• copy • arc• paste • pie slice• apply mask • text
  15. 15. Operations • resize • ellipse • rotate • polygon • crop • line • save • dot • copy • arc • paste • pie slice • apply mask • textmanipulations
  16. 16. Operations• resize • ellipse• rotate • polygon• crop • line• save • dot• copy • arc• paste • pie slice• apply mask • text drawings
  17. 17. Example
  18. 18. Thumbnail
  19. 19. Thumbnail$imagine = new ImagineGdImagine();$mode = ImagineImageInterface::THUMBNAIL_OUTBOUND;//or$mode = ImagineImageInterface::THUMBNAIL_INSET;$imagine->open(/path/to/google/logo.png) ->thumbnail(new ImagineBox(100, 100), $mode) ->save(/path/to/google/logo/thumbnail.png);
  20. 20. Reflection
  21. 21. Reflection$imagine = new ImagineGdImagine();$logo = $imagine->open(/path/to/google/logo.png);$size = $logo->getSize();$canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2), new ImagineColor(000, 100));$reflection = $logo->copy() ->flipVertically() ->applyMask( $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) );$canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  22. 22. Reflection $imagine = new ImagineGdImagine(); $logo = $imagine->open(/path/to/google/logo.png); $size = $logo->getSize(); $canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2 + 1), new ImagineColor(000, 100) ); $reflection = $logo->copy() ->flipVertically()open image to reflect and remember its size ->applyMask( $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) ); $canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  23. 23. Reflection $imagine = new ImagineGdImagine(); $logo = $imagine->open(/path/to/google/logo.png); $size = $logo->getSize(); $canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2), new ImagineColor(000, 100) ); $reflection = $logo->copy() ->flipVertically()create empty canvas to fit image and reflection ->applyMask( $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) ); $canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  24. 24. Reflection $imagine = new ImagineGdImagine(); $logo = $imagine->open(/path/to/google/logo.png); $size = $logo->getSize(); $canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2), new ImagineColor(000, 100) ); $reflection = $logo->copy() ->flipVertically()make a copy of source, flipped vertically ->applyMask( $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) ); $canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  25. 25. Reflection $imagine = new ImagineGdImagine(); $logo = $imagine->open(/path/to/google/logo.png); $size = $logo->getSize(); $canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2), new ImagineColor(000, 100) );replace white regions with transparency $reflection = $logo->copy() ->flipVertically() ->applyMask( $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) ); $canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  26. 26. Reflection$imagine = new ImagineGdImagine();$logo = $imagine->open(/path/to/google/logo.png);$size = $logo->getSize();$canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2), new ImagineColor(000, 100)); create image like the one above$reflection = $logo->copy() ->flipVertically() ->applyMask( $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) );$canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  27. 27. Reflection $imagine = new ImagineGdImagine(); $logo = $imagine->open(/path/to/google/logo.png); $size = $logo->getSize(); $canvas = $imagine->create( new ImagineBox($size->getWidth(), $size->getHeight() * 2), new ImagineColor(000, 100) ); $reflection = $logo->copy()place original logo on top of created canvas ->flipVertically() ->applyMask( place reflection underneath it $imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), new ImagineColor(array(127, 127, 127)), new ImagineColor(fff) ) ) ); $canvas->paste($logo, new ImaginePoint(0, 0)) ->paste($reflection, new ImaginePoint(0, $size->getHeight())) ->save(/path/to/google/logo/reflection.png);
  28. 28. Piechart
  29. 29. $imagine = Piechart new ImagineImagickImagine();$volume = 20;$size = new ImagineBox(300, 200);$center = new ImaginePointCenter($size);$canvas = $size->increase($volume);$bg = new ImagineColor(000000, 100);$color1 = new ImagineColor(FFEF78);$color2 = new ImagineColor(8A834B);$color3 = new ImagineColor(8A554B);$color4 = new ImagineColor(D94616);$color5 = new ImagineColor(FEB48D);$chart = $imagine->create($canvas, $bg);for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i); $chart->draw() ->pieSlice($shift, $size, -10, 70, $color1->darken(68), true) ->pieSlice($shift, $size, 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true);}$chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true);$chart->save(/path/to/chart.png);
  30. 30. $imagine = Piechart new ImagineImagickImagine(); $volume = 20; $size = new ImagineBox(300, 200); $center = new ImaginePointCenter($size); $canvas = $size->increase($volume); $bg = new ImagineColor(000000, 100); $color1 = new ImagineColor(FFEF78); $color2 = new ImagineColor(8A834B); $color3 = new ImagineColor(8A554B); $color4 = new ImagineColor(D94616); $color5 = new ImagineColor(FEB48D); $chart = $imagine->create($canvas, $bg); for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i);get imagine, define chart 3d volume and size $chart->draw() ->pieSlice($shift, $size, -10, 70, $color1->darken(68), true) ->pieSlice($shift, $size, 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true); } $chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true); $chart->save(/path/to/chart.png);
  31. 31. $imagine = Piechart new ImagineImagickImagine(); $volume = 20; $size = new ImagineBox(300, 200); $center = new ImaginePointCenter($size); $canvas = $size->increase($volume); $bg = new ImagineColor(000000, 100); $color1 = new ImagineColor(FFEF78); $color2 = new ImagineColor(8A834B); $color3 = new ImagineColor(8A554B); $color4 = new ImagineColor(D94616); $color5 = new ImagineColor(FEB48D); $chart = $imagine->create($canvas, $bg); get center of the chart for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i);account for size of 3d volume in canvas $chart->draw() ->pieSlice($shift, ->pieSlice($shift, $size, $size, -10, 70, $color1->darken(68), true) 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true); } $chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true); $chart->save(/path/to/chart.png);
  32. 32. $imagine = Piechart new ImagineImagickImagine();$volume = 20;$size = new ImagineBox(300, 200);$center = new ImaginePointCenter($size);$canvas = $size->increase($volume);$bg = new ImagineColor(000000, 100);$color1 = new ImagineColor(FFEF78);$color2 = new ImagineColor(8A834B);$color3 = new ImagineColor(8A554B);$color4 = new ImagineColor(D94616);$color5 = new ImagineColor(FEB48D);$chart = $imagine->create($canvas, $bg);for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i);colors of pie slices and background $chart->draw() ->pieSlice($shift, $size, -10, 70, $color1->darken(68), true) ->pieSlice($shift, $size, 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true);}$chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true); http://www.colourlovers.com/palette/1472972/jeniffer123@yahoo$chart->save(/path/to/chart.png);
  33. 33. $imagine = Piechart new ImagineImagickImagine(); $volume = 20; $size = new ImagineBox(300, 200); $center = new ImaginePointCenter($size); $canvas = $size->increase($volume); $bg = new ImagineColor(000000, 100); $color1 = new ImagineColor(FFEF78); $color2 = new ImagineColor(8A834B); $color3 = new ImagineColor(8A554B); $color4 = new ImagineColor(D94616); $color5 = new ImagineColor(FEB48D); $chart = $imagine->create($canvas, $bg); for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i);create chart canvas with transparent background $chart->draw() ->pieSlice($shift, $size, -10, 70, $color1->darken(68), true) ->pieSlice($shift, $size, 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true); } $chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true); $chart->save(/path/to/chart.png);
  34. 34. $imagine = Piechart new ImagineImagickImagine(); $volume = 20; $size = new ImagineBox(300, 200); $center = new ImaginePointCenter($size); $canvas = $size->increase($volume); $bg = new ImagineColor(000000, 100); $color1 = new ImagineColor(FFEF78); $color2 = new ImagineColor(8A834B); $color3 = new ImagineColor(8A554B); $color4 = new ImagineColor(D94616); $color5 = new ImagineColor(FEB48D);build 3d shade of the chart in darker colors $chart = $imagine->create($canvas, $bg); for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i); $chart->draw() ->pieSlice($shift, $size, -10, 70, $color1->darken(68), true) ->pieSlice($shift, $size, 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true); } $chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true); $chart->save(/path/to/chart.png);
  35. 35. $imagine = Piechart new ImagineImagickImagine();$volume = 20;$size = new ImagineBox(300, 200);$center = new ImaginePointCenter($size);$canvas = $size->increase($volume);$bg = new ImagineColor(000000, 100);$color1 = new ImagineColor(FFEF78);$color2 = new ImagineColor(8A834B);$color3 = new ImagineColor(8A554B);$color4 = new ImagineColor(D94616);$color5 = new ImagineColor(FEB48D);$chart = $imagine->create($canvas, $bg);for ($i = $volume; $i > 0; $i--) { $shift = new ImaginePoint($center->getX() + $i, $center->getY() + $i); draw and save the actual chart $chart->draw() ->pieSlice($shift, $size, -10, 70, $color1->darken(68), true) ->pieSlice($shift, $size, 70, 160, $color2->darken(68), true) ->pieSlice($shift, $size, 160, 170, $color3->darken(68), true) ->pieSlice($shift, $size, 170, 210, $color4->darken(68), true) ->pieSlice($shift, $size, 210, 350, $color5->darken(68), true);}$chart->draw() ->pieSlice($center, $size, -10, 70, $color1, true) ->pieSlice($center, $size, 70, 160, $color2, true) ->pieSlice($center, $size, 160, 170, $color3, true) ->pieSlice($center, $size, 170, 210, $color4, true) ->pieSlice($center, $size, 210, 350, $color5, true);$chart->save(/path/to/chart.png);
  36. 36. Simplify1. use value objects to group related parameters2. make those objects smart, to remove repeated code
  37. 37. Color$color = new ImagineColor(fff);$color->darken(127);$color->dissolve(50);$color->darken(68)->dissolve(50);
  38. 38. Box$box = new ImagineBox(100, 100);$box->scale(2);$box->increase(25);
  39. 39. Point$point = new ImaginePoint(50, 50);
  40. 40. Make it testable1. provide interfaces that interact with end user code2. close unexpected inheritance
  41. 41. Filters
  42. 42. Filternamespace ImagineFilter;use ImagineImageInterface;interface FilterInterface{ /** * Applies scheduled transformation to ImageInterface instance * Returns processed ImageInterface instance * * @param ImagineImageInterface $image * * @return ImagineImageInterface */ function apply(ImageInterface $image);}
  43. 43. FiltersFilter is a collection of manipulations, calculations and other operations, that can be applied to an image
  44. 44. Reflection filterclass ReflectionFilter implements ImagineFilterFilterInterface{ private $imagine; public function __construct(ImagineImagineInterface $imagine) { $this->imagine = $imagine; } public function apply(ImagineImageInterface $image) { $size = $image->getSize(); $white = new ImagineColor(fff); $canvas = new ImagineBox($size->getWidth(), $size->getHeight() * 2); return $this->imagine->create($canvas) ->paste($image, new ImaginePoint(0, 0)) ->paste($logo->copy() ->flipVertically() ->applyMask($this->imagine->create($size) ->fill( new ImagineFillGradientVertical( $size->getHeight(), $white->darken(127), $white ) ) )); }}
  45. 45. Reflection filter$imagine = new ImagineGdImagine();$filter = new ReflectionFilter($imagine);$filter->apply($imagine->open(/path/to/google/logo.png)) ->save(/path/to/google/logo/reflection.png);
  46. 46. TransformationDelayed image processing using a filter
  47. 47. Transformation $path = /path/to/processed/image.png; $size = new ImagineBox(50, 50); $resize = new ImagineBox(200, 200); $angle = 90; $background = new ImagineColor(fff); $transformation = new ImagineFilterTransformation(); $transformation->resize($resize) ->copy() ->rotate($angle, $background) ->thumbnail($size, ImageInterface::THUMBNAIL_INSET) ->save($path);operate on a transformation as on a regular image, except nothing is being executed
  48. 48. Transformation$transformation->apply($imagine->open(/path/to/source/image.png)); Apply them when you’re ready
  49. 49. Transformationforeach(glob(/path/to/many/images/*.png) as $path) { $transformation->apply($imagine->open($path)) ->save(/path/to/processed/image/.md5($path)..png);} Or even batch process...
  50. 50. What’s next?• Implement charting API (piecharts, bar- charts, linear graphs)• Add advanced filters (reflection, rounded corners, etc.)• Add effects (twirl, blur, sharpen, etc.)
  51. 51. Imagineimage processing reloaded https://github.com/avalanche123/Imagine

×