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 (6)

1 uk political system
1 uk political system1 uk political system
1 uk political system
 
Data cleaning using Excel
Data cleaning using ExcelData cleaning using Excel
Data cleaning using Excel
 
Civil service in developed & developing countries a comparative study
Civil service in developed & developing countries   a comparative studyCivil service in developed & developing countries   a comparative study
Civil service in developed & developing countries a comparative study
 
Treeview listview
Treeview listviewTreeview listview
Treeview listview
 
Industrial Revolution And Its Impact On Public Administration
Industrial Revolution And Its Impact On Public AdministrationIndustrial Revolution And Its Impact On Public Administration
Industrial Revolution And Its Impact On Public Administration
 
Public Administration: Three Problems
Public Administration: Three ProblemsPublic Administration: Three Problems
Public Administration: Three Problems
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Recently uploaded (20)

EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
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
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
"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 ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
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
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
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
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.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