SlideShare a Scribd company logo
1 of 62
Download to read offline
Introduction to Imagine
                          image processing for PHP 5.3+

                             http://goo.gl/T994G




Saturday, March 5, 2011
Image processing in
                             PHP is hard


Saturday, March 5, 2011
There are many
                              existing tools
                          • GD
                          • Imagick (ImageMagick extension)
                          • Gmagick (GraphicsMagick extension)
                          • Cairo
                                      http://www.imagemagick.org/
                                     http://www.graphicsmagick.org/

Saturday, March 5, 2011
Existing tools are

                               • not testable
                               • inconsistent
                               • cluttered apis
                               • not intuitive

Saturday, March 5, 2011
$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
Saturday, March 5, 2011
$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
Saturday, March 5, 2011
Existing tools


                            don’t cut it




Saturday, March 5, 2011
Imagine...

                     • all drivers implemented the same interfaces
                     • code could be reused with any driver
                     • there were interfaces for mocking in tests
                     • API was simple and intuitive

Saturday, March 5, 2011
STOP



Saturday, March 5, 2011
Imagine for PHP 5.3+


                             stop imagining, it is all there




Saturday, March 5, 2011
Imagine for PHP 5.3+


                              Inspired by Python’s PIL




                                http://www.pythonware.com/products/pil/


Saturday, March 5, 2011
$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)
Saturday, March 5, 2011
$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)
Saturday, March 5, 2011
Consistency

                          1. identify operations
                          2. split into groups
                          3. implement per driver




Saturday, March 5, 2011
Operations
                          •   resize       •   ellipse

                          •   rotate       •   polygon

                          •   crop         •   line

                          •   save         •   dot

                          •   copy         •   arc

                          •   paste        •   pie slice

                          •   apply mask   •   text


Saturday, March 5, 2011
Operations
                          •   resize       •   ellipse

                          •   rotate       •   polygon

                          •   crop         •   line

                          •   save         •   dot

                          •   copy         •   arc

                          •   paste        •   pie slice

                          •   apply mask   •   text

                          manipulations
Saturday, March 5, 2011
Operations
                          •   resize       •   ellipse

                          •   rotate       •   polygon

                          •   crop         •   line

                          •   save         •   dot

                          •   copy         •   arc

                          •   paste        •   pie slice

                          •   apply mask   •   text

                          manipulations
Saturday, March 5, 2011
Operations
                          •   resize       •   ellipse

                          •   rotate       •   polygon

                          •   crop         •   line

                          •   save         •   dot

                          •   copy         •   arc

                          •   paste        •   pie slice

                          •   apply mask   •   text

                                           drawings
Saturday, March 5, 2011
Operations
                          •   resize       •   ellipse

                          •   rotate       •   polygon

                          •   crop         •   line

                          •   save         •   dot

                          •   copy         •   arc

                          •   paste        •   pie slice

                          •   apply mask   •   text

                                           drawings
Saturday, March 5, 2011
Example




Saturday, March 5, 2011
Thumbnail




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
Reflection




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
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');




Saturday, March 5, 2011
Piechart




Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
$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');



Saturday, March 5, 2011
Simplify


                          1. use value objects
                          2. make ‘em smart




Saturday, March 5, 2011
Color
                $color = new ImagineColor('fff');

                $color->darken(127);

                $color->dissolve(50);

                $color->darken(68)->dissolve(50);




Saturday, March 5, 2011
Box
                      $box = new ImagineBox(100, 100);
                                     100




                                           100            $box->scale(2);
                                                                200




                                                                        200

                            $box->increase(25);

                                     125




                                             125




Saturday, March 5, 2011
Point



                          $point = new ImaginePoint(50, 50);




Saturday, March 5, 2011
Make it testable


                          1. interface end user code interactions
                          2. close unexpected inheritance




Saturday, March 5, 2011
Filters



Saturday, March 5, 2011
Filter
                          namespace ImagineFilter;

                          use ImagineImageInterface;

                          interface FilterInterface
                          {
                              /**
                               * Applies scheduled transformation to ImageInterface instance
                               * Returns processed ImageInterface instance
                               *
                               * @param ImagineImageInterface $image
                               *
                               * @return ImagineImageInterface
                               */
                              function apply(ImageInterface $image);
                          }




Saturday, March 5, 2011
Filters

Filter is a collection of manipulations, calculations and other
          operations, that can be applied to an image




Saturday, March 5, 2011
Reflection filter
                          class 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
                                                  )
                                              )
                                          ));
                              }
                          }



Saturday, March 5, 2011
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');




Saturday, March 5, 2011
Transformation
                          Delayed image processing using a filter




Saturday, March 5, 2011
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, ImagineImageInterface::THUMBNAIL_INSET)
                              ->save($path);




 operate on a transformation as on a regular image, except
                 nothing is being executed

Saturday, March 5, 2011
Transformation

  $transformation->apply($imagine->open('/path/to/source/image.png'));




                          Apply them when you’re ready



Saturday, March 5, 2011
Transformation

          foreach(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...



Saturday, March 5, 2011
Imagine and Symfony2



Saturday, March 5, 2011
Integration

                          1. configure
                          2. use in templates
                          3. profit




Saturday, March 5, 2011
Configure

                 avalanche_imagine:
                     web_root:      %kernel.root_dir%/../web
                     driver:        gd
                     filters:
                         preview:
                              type:    thumbnail
                              options: { size: [100, 50], mode: outbound }




Saturday, March 5, 2011
Templates

                          <img src="{{ user.photo|apply_filter('preview') }}" alt="avatar" />


                                                             Twig

                  <img src="<?php echo $view['imagine']->filter($user->getPhoto(), 'preview') ?>" alt="avatar" />



                                                             PHP




Saturday, March 5, 2011
Process

           <img src="/imagine/preview/users/1/photo.jpg" alt="avatar" />




           first request processes image and outputs response


     other controller requests result in a 301 redirect to file


Saturday, March 5, 2011
Summary



Saturday, March 5, 2011
To be improved
                     • advanced operations are still not easy
                     • not all drivers are supported
                      • Imagick
                      • GD
                      • Gmagick
                     • library is very young, there might be issues
Saturday, March 5, 2011
Was improved

                     • thumbnails are easy
                     • code is readable
                     • foundation is solid
                     • its available today
                     • its gonna be great

Saturday, March 5, 2011
What’s next?
                     • Documentation
                     • Implement charting API (piecharts, bar-
                          charts, linear graphs)
                     • Add advanced filters (reflection, rounded
                          corners, etc.)
                     • Add effects (twirl, blur, sharpen, etc.)

Saturday, March 5, 2011
Imagine
                          image processing reloaded

                            https://github.com/avalanche123/Imagine




Saturday, March 5, 2011

More Related Content

What's hot

HTML5 - Forms
HTML5 - FormsHTML5 - Forms
HTML5 - Forms
tina1357
 

What's hot (20)

Java EE Introduction
Java EE IntroductionJava EE Introduction
Java EE Introduction
 
Json in Postgres - the Roadmap
 Json in Postgres - the Roadmap Json in Postgres - the Roadmap
Json in Postgres - the Roadmap
 
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
 
Nifi
NifiNifi
Nifi
 
初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準
 
Angular 9
Angular 9 Angular 9
Angular 9
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Angular
AngularAngular
Angular
 
Netflix conductor
Netflix conductorNetflix conductor
Netflix conductor
 
Javascript and DOM
Javascript and DOMJavascript and DOM
Javascript and DOM
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
 
Xml ppt
Xml pptXml ppt
Xml ppt
 
HTML5 - Forms
HTML5 - FormsHTML5 - Forms
HTML5 - Forms
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
java Servlet technology
java Servlet technologyjava Servlet technology
java Servlet technology
 
Javascript
JavascriptJavascript
Javascript
 
React&redux
React&reduxReact&redux
React&redux
 
Advanced Model Inferencing leveraging Kubeflow Serving, KNative and Istio
Advanced Model Inferencing leveraging Kubeflow Serving, KNative and IstioAdvanced Model Inferencing leveraging Kubeflow Serving, KNative and Istio
Advanced Model Inferencing leveraging Kubeflow Serving, KNative and Istio
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 

Introduction to Imagine

  • 1. Introduction to Imagine image processing for PHP 5.3+ http://goo.gl/T994G Saturday, March 5, 2011
  • 2. Image processing in PHP is hard Saturday, March 5, 2011
  • 3. There are many existing tools • GD • Imagick (ImageMagick extension) • Gmagick (GraphicsMagick extension) • Cairo http://www.imagemagick.org/ http://www.graphicsmagick.org/ Saturday, March 5, 2011
  • 4. Existing tools are • not testable • inconsistent • cluttered apis • not intuitive Saturday, March 5, 2011
  • 5. $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 Saturday, March 5, 2011
  • 6. $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 Saturday, March 5, 2011
  • 7. Existing tools don’t cut it Saturday, March 5, 2011
  • 8. Imagine... • all drivers implemented the same interfaces • code could be reused with any driver • there were interfaces for mocking in tests • API was simple and intuitive Saturday, March 5, 2011
  • 10. Imagine for PHP 5.3+ stop imagining, it is all there Saturday, March 5, 2011
  • 11. Imagine for PHP 5.3+ Inspired by Python’s PIL http://www.pythonware.com/products/pil/ Saturday, March 5, 2011
  • 12. $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) Saturday, March 5, 2011
  • 13. $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) Saturday, March 5, 2011
  • 14. Consistency 1. identify operations 2. split into groups 3. implement per driver Saturday, March 5, 2011
  • 15. Operations • resize • ellipse • rotate • polygon • crop • line • save • dot • copy • arc • paste • pie slice • apply mask • text Saturday, March 5, 2011
  • 16. Operations • resize • ellipse • rotate • polygon • crop • line • save • dot • copy • arc • paste • pie slice • apply mask • text manipulations Saturday, March 5, 2011
  • 17. Operations • resize • ellipse • rotate • polygon • crop • line • save • dot • copy • arc • paste • pie slice • apply mask • text manipulations Saturday, March 5, 2011
  • 18. Operations • resize • ellipse • rotate • polygon • crop • line • save • dot • copy • arc • paste • pie slice • apply mask • text drawings Saturday, March 5, 2011
  • 19. Operations • resize • ellipse • rotate • polygon • crop • line • save • dot • copy • arc • paste • pie slice • apply mask • text drawings Saturday, March 5, 2011
  • 22. 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'); Saturday, March 5, 2011
  • 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() ->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'); Saturday, March 5, 2011
  • 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 + 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'); Saturday, March 5, 2011
  • 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) ); $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'); Saturday, March 5, 2011
  • 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() ->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'); Saturday, March 5, 2011
  • 28. 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'); Saturday, March 5, 2011
  • 29. 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'); Saturday, March 5, 2011
  • 30. 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'); Saturday, March 5, 2011
  • 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); $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'); Saturday, March 5, 2011
  • 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); 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'); Saturday, March 5, 2011
  • 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'); $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'); Saturday, March 5, 2011
  • 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); 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'); Saturday, March 5, 2011
  • 36. $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'); Saturday, March 5, 2011
  • 37. $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'); Saturday, March 5, 2011
  • 38. $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'); Saturday, March 5, 2011
  • 39. Simplify 1. use value objects 2. make ‘em smart Saturday, March 5, 2011
  • 40. Color $color = new ImagineColor('fff'); $color->darken(127); $color->dissolve(50); $color->darken(68)->dissolve(50); Saturday, March 5, 2011
  • 41. Box $box = new ImagineBox(100, 100); 100 100 $box->scale(2); 200 200 $box->increase(25); 125 125 Saturday, March 5, 2011
  • 42. Point $point = new ImaginePoint(50, 50); Saturday, March 5, 2011
  • 43. Make it testable 1. interface end user code interactions 2. close unexpected inheritance Saturday, March 5, 2011
  • 45. Filter namespace ImagineFilter; use ImagineImageInterface; interface FilterInterface { /** * Applies scheduled transformation to ImageInterface instance * Returns processed ImageInterface instance * * @param ImagineImageInterface $image * * @return ImagineImageInterface */ function apply(ImageInterface $image); } Saturday, March 5, 2011
  • 46. Filters Filter is a collection of manipulations, calculations and other operations, that can be applied to an image Saturday, March 5, 2011
  • 47. Reflection filter class 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 ) ) )); } } Saturday, March 5, 2011
  • 48. 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'); Saturday, March 5, 2011
  • 49. Transformation Delayed image processing using a filter Saturday, March 5, 2011
  • 50. 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, ImagineImageInterface::THUMBNAIL_INSET) ->save($path); operate on a transformation as on a regular image, except nothing is being executed Saturday, March 5, 2011
  • 51. Transformation $transformation->apply($imagine->open('/path/to/source/image.png')); Apply them when you’re ready Saturday, March 5, 2011
  • 52. Transformation foreach(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... Saturday, March 5, 2011
  • 54. Integration 1. configure 2. use in templates 3. profit Saturday, March 5, 2011
  • 55. Configure avalanche_imagine: web_root: %kernel.root_dir%/../web driver: gd filters: preview: type: thumbnail options: { size: [100, 50], mode: outbound } Saturday, March 5, 2011
  • 56. Templates <img src="{{ user.photo|apply_filter('preview') }}" alt="avatar" /> Twig <img src="<?php echo $view['imagine']->filter($user->getPhoto(), 'preview') ?>" alt="avatar" /> PHP Saturday, March 5, 2011
  • 57. Process <img src="/imagine/preview/users/1/photo.jpg" alt="avatar" /> first request processes image and outputs response other controller requests result in a 301 redirect to file Saturday, March 5, 2011
  • 59. To be improved • advanced operations are still not easy • not all drivers are supported • Imagick • GD • Gmagick • library is very young, there might be issues Saturday, March 5, 2011
  • 60. Was improved • thumbnails are easy • code is readable • foundation is solid • its available today • its gonna be great Saturday, March 5, 2011
  • 61. What’s next? • Documentation • Implement charting API (piecharts, bar- charts, linear graphs) • Add advanced filters (reflection, rounded corners, etc.) • Add effects (twirl, blur, sharpen, etc.) Saturday, March 5, 2011
  • 62. Imagine image processing reloaded https://github.com/avalanche123/Imagine Saturday, March 5, 2011