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

Système Information - ETL et EAI - Décisionnel et Opérationnel
Système Information - ETL et EAI - Décisionnel et OpérationnelSystème Information - ETL et EAI - Décisionnel et Opérationnel
Système Information - ETL et EAI - Décisionnel et OpérationnelFrédéric FAURE
 
Evolution of the Graph Schema
Evolution of the Graph SchemaEvolution of the Graph Schema
Evolution of the Graph SchemaJoshua Shinavier
 
BigData_Chp5: Putting it all together
BigData_Chp5: Putting it all togetherBigData_Chp5: Putting it all together
BigData_Chp5: Putting it all togetherLilia Sfaxi
 
Cours Big Data Chap5
Cours Big Data Chap5Cours Big Data Chap5
Cours Big Data Chap5Amal Abid
 
Building the Rail Network Digital Twin at CSX
Building the Rail Network Digital Twin at CSXBuilding the Rail Network Digital Twin at CSX
Building the Rail Network Digital Twin at CSXNeo4j
 
MongoDB at eBay
MongoDB at eBayMongoDB at eBay
MongoDB at eBayMongoDB
 
Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5
Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5
Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5ISACA Chapitre de Québec
 
Cours Big Data Chap1
Cours Big Data Chap1Cours Big Data Chap1
Cours Big Data Chap1Amal Abid
 
Identifier les risques
Identifier les risquesIdentifier les risques
Identifier les risquesCarine Pascal
 
Cahier des charges pour la création d'un data warehouse medical
Cahier des charges pour la création d'un data warehouse medicalCahier des charges pour la création d'un data warehouse medical
Cahier des charges pour la création d'un data warehouse medicalVincent H. Hupertan
 
Oracle GoldenGate on Docker
Oracle GoldenGate on DockerOracle GoldenGate on Docker
Oracle GoldenGate on DockerBobby Curtis
 
Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...
Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...
Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...Red Room
 
Outilsdanalysefonctionnellesadt 160919140831
Outilsdanalysefonctionnellesadt 160919140831Outilsdanalysefonctionnellesadt 160919140831
Outilsdanalysefonctionnellesadt 160919140831Lénaïc CAPELLE
 
Présentation data warehouse etl et olap
Présentation data warehouse etl et olapPrésentation data warehouse etl et olap
Présentation data warehouse etl et olapCynapsys It Hotspot
 
Running Siebel on AWS - Oracle Open World 13
Running Siebel on AWS - Oracle Open World 13Running Siebel on AWS - Oracle Open World 13
Running Siebel on AWS - Oracle Open World 13Milind Waikul
 
Apache Hadoop YARN: best practices
Apache Hadoop YARN: best practicesApache Hadoop YARN: best practices
Apache Hadoop YARN: best practicesDataWorks Summit
 
Spark (v1.3) - Présentation (Français)
Spark (v1.3) - Présentation (Français)Spark (v1.3) - Présentation (Français)
Spark (v1.3) - Présentation (Français)Alexis Seigneurin
 
Business Intelligence
Business IntelligenceBusiness Intelligence
Business IntelligenceLilia Sfaxi
 

What's hot (20)

Système Information - ETL et EAI - Décisionnel et Opérationnel
Système Information - ETL et EAI - Décisionnel et OpérationnelSystème Information - ETL et EAI - Décisionnel et Opérationnel
Système Information - ETL et EAI - Décisionnel et Opérationnel
 
Evolution of the Graph Schema
Evolution of the Graph SchemaEvolution of the Graph Schema
Evolution of the Graph Schema
 
BigData_Chp5: Putting it all together
BigData_Chp5: Putting it all togetherBigData_Chp5: Putting it all together
BigData_Chp5: Putting it all together
 
Cours Big Data Chap5
Cours Big Data Chap5Cours Big Data Chap5
Cours Big Data Chap5
 
Building the Rail Network Digital Twin at CSX
Building the Rail Network Digital Twin at CSXBuilding the Rail Network Digital Twin at CSX
Building the Rail Network Digital Twin at CSX
 
MongoDB at eBay
MongoDB at eBayMongoDB at eBay
MongoDB at eBay
 
Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5
Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5
Évolution des bonnes pratiques en sécurité de l'information avec COBIT 5
 
Cours Big Data Chap1
Cours Big Data Chap1Cours Big Data Chap1
Cours Big Data Chap1
 
Identifier les risques
Identifier les risquesIdentifier les risques
Identifier les risques
 
Cahier des charges pour la création d'un data warehouse medical
Cahier des charges pour la création d'un data warehouse medicalCahier des charges pour la création d'un data warehouse medical
Cahier des charges pour la création d'un data warehouse medical
 
Oracle GoldenGate on Docker
Oracle GoldenGate on DockerOracle GoldenGate on Docker
Oracle GoldenGate on Docker
 
Resume de BI
Resume de BIResume de BI
Resume de BI
 
Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...
Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...
Une Approche Multi Agents D’identification Précoce Des Interactions Entre Les...
 
Outilsdanalysefonctionnellesadt 160919140831
Outilsdanalysefonctionnellesadt 160919140831Outilsdanalysefonctionnellesadt 160919140831
Outilsdanalysefonctionnellesadt 160919140831
 
Hive: Loading Data
Hive: Loading DataHive: Loading Data
Hive: Loading Data
 
Présentation data warehouse etl et olap
Présentation data warehouse etl et olapPrésentation data warehouse etl et olap
Présentation data warehouse etl et olap
 
Running Siebel on AWS - Oracle Open World 13
Running Siebel on AWS - Oracle Open World 13Running Siebel on AWS - Oracle Open World 13
Running Siebel on AWS - Oracle Open World 13
 
Apache Hadoop YARN: best practices
Apache Hadoop YARN: best practicesApache Hadoop YARN: best practices
Apache Hadoop YARN: best practices
 
Spark (v1.3) - Présentation (Français)
Spark (v1.3) - Présentation (Français)Spark (v1.3) - Présentation (Français)
Spark (v1.3) - Présentation (Français)
 
Business Intelligence
Business IntelligenceBusiness Intelligence
Business Intelligence
 

Recently uploaded

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 

Recently uploaded (20)

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

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