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

Ensemble Learning: The Wisdom of Crowds (of Machines)
Ensemble Learning: The Wisdom of Crowds (of Machines)Ensemble Learning: The Wisdom of Crowds (of Machines)
Ensemble Learning: The Wisdom of Crowds (of Machines)Lior Rokach
 
Causal Inference : Primer (2019-06-01 잔디콘)
Causal Inference : Primer (2019-06-01 잔디콘)Causal Inference : Primer (2019-06-01 잔디콘)
Causal Inference : Primer (2019-06-01 잔디콘)Minho Lee
 
[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA
[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA
[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnABokyung Choi
 
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스BOAZ Bigdata
 
Building Data Pipelines for Music Recommendations at Spotify
Building Data Pipelines for Music Recommendations at SpotifyBuilding Data Pipelines for Music Recommendations at Spotify
Building Data Pipelines for Music Recommendations at SpotifyVidhya Murali
 
슬라이드쉐어
슬라이드쉐어슬라이드쉐어
슬라이드쉐어sungminlee
 
InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...
InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...
InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...홍배 김
 
[DL輪読会]Deep Learning 第5章 機械学習の基礎
[DL輪読会]Deep Learning 第5章 機械学習の基礎[DL輪読会]Deep Learning 第5章 機械学習の基礎
[DL輪読会]Deep Learning 第5章 機械学習の基礎Deep Learning JP
 
Music Recommendations at Scale with Spark
Music Recommendations at Scale with SparkMusic Recommendations at Scale with Spark
Music Recommendations at Scale with SparkChris Johnson
 
A Review of Deep Contextualized Word Representations (Peters+, 2018)
A Review of Deep Contextualized Word Representations (Peters+, 2018)A Review of Deep Contextualized Word Representations (Peters+, 2018)
A Review of Deep Contextualized Word Representations (Peters+, 2018)Shuntaro Yada
 
Applied Deep Learning 11/03 Convolutional Neural Networks
Applied Deep Learning 11/03 Convolutional Neural NetworksApplied Deep Learning 11/03 Convolutional Neural Networks
Applied Deep Learning 11/03 Convolutional Neural NetworksMark Chang
 
파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304Yong Joon Moon
 
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...taeseon ryu
 
Algorithmic Music Recommendations at Spotify
Algorithmic Music Recommendations at SpotifyAlgorithmic Music Recommendations at Spotify
Algorithmic Music Recommendations at SpotifyChris Johnson
 
[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...
[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...
[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...Taiji Suzuki
 
[DL輪読会]Deep Learning 第12章 アプリケーション
[DL輪読会]Deep Learning 第12章 アプリケーション[DL輪読会]Deep Learning 第12章 アプリケーション
[DL輪読会]Deep Learning 第12章 アプリケーションDeep Learning JP
 
[논문리뷰] 딥러닝 적용한 EEG 연구 소개
[논문리뷰] 딥러닝 적용한 EEG 연구 소개[논문리뷰] 딥러닝 적용한 EEG 연구 소개
[논문리뷰] 딥러닝 적용한 EEG 연구 소개Donghyeon Kim
 
High Dimensional Data Visualization using t-SNE
High Dimensional Data Visualization using t-SNEHigh Dimensional Data Visualization using t-SNE
High Dimensional Data Visualization using t-SNEKai-Wen Zhao
 

What's hot (20)

Ensemble Learning: The Wisdom of Crowds (of Machines)
Ensemble Learning: The Wisdom of Crowds (of Machines)Ensemble Learning: The Wisdom of Crowds (of Machines)
Ensemble Learning: The Wisdom of Crowds (of Machines)
 
CNN
CNNCNN
CNN
 
Causal Inference : Primer (2019-06-01 잔디콘)
Causal Inference : Primer (2019-06-01 잔디콘)Causal Inference : Primer (2019-06-01 잔디콘)
Causal Inference : Primer (2019-06-01 잔디콘)
 
[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA
[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA
[PAP] 팝콘 시즌 1 컨퍼런스 사전 QnA
 
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스
제 16회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [기린그림 팀] : 사용자의 손글씨가 담긴 그림 일기 생성 서비스
 
Building Data Pipelines for Music Recommendations at Spotify
Building Data Pipelines for Music Recommendations at SpotifyBuilding Data Pipelines for Music Recommendations at Spotify
Building Data Pipelines for Music Recommendations at Spotify
 
슬라이드쉐어
슬라이드쉐어슬라이드쉐어
슬라이드쉐어
 
InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...
InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...
InfoGAN: Interpretable Representation Learning by Information Maximizing Gene...
 
[DL輪読会]Deep Learning 第5章 機械学習の基礎
[DL輪読会]Deep Learning 第5章 機械学習の基礎[DL輪読会]Deep Learning 第5章 機械学習の基礎
[DL輪読会]Deep Learning 第5章 機械学習の基礎
 
Music Recommendations at Scale with Spark
Music Recommendations at Scale with SparkMusic Recommendations at Scale with Spark
Music Recommendations at Scale with Spark
 
A Review of Deep Contextualized Word Representations (Peters+, 2018)
A Review of Deep Contextualized Word Representations (Peters+, 2018)A Review of Deep Contextualized Word Representations (Peters+, 2018)
A Review of Deep Contextualized Word Representations (Peters+, 2018)
 
Applied Deep Learning 11/03 Convolutional Neural Networks
Applied Deep Learning 11/03 Convolutional Neural NetworksApplied Deep Learning 11/03 Convolutional Neural Networks
Applied Deep Learning 11/03 Convolutional Neural Networks
 
파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304
 
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
 
Data Science. Intro
Data Science. IntroData Science. Intro
Data Science. Intro
 
Algorithmic Music Recommendations at Spotify
Algorithmic Music Recommendations at SpotifyAlgorithmic Music Recommendations at Spotify
Algorithmic Music Recommendations at Spotify
 
[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...
[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...
[ICLR2021 (spotlight)] Benefit of deep learning with non-convex noisy gradien...
 
[DL輪読会]Deep Learning 第12章 アプリケーション
[DL輪読会]Deep Learning 第12章 アプリケーション[DL輪読会]Deep Learning 第12章 アプリケーション
[DL輪読会]Deep Learning 第12章 アプリケーション
 
[논문리뷰] 딥러닝 적용한 EEG 연구 소개
[논문리뷰] 딥러닝 적용한 EEG 연구 소개[논문리뷰] 딥러닝 적용한 EEG 연구 소개
[논문리뷰] 딥러닝 적용한 EEG 연구 소개
 
High Dimensional Data Visualization using t-SNE
High Dimensional Data Visualization using t-SNEHigh Dimensional Data Visualization using t-SNE
High Dimensional Data Visualization using t-SNE
 

Recently uploaded

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
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
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 

Recently uploaded (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
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
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 

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