Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pixel Punching with PHP

Pixel Punching with PHP

This is the version of the presentation I gave at Lone Star PHP 2012 in Dallas. It covers basic image manipulation in both GD and Imagick.

Bob Majdak Jr

June 30, 2012
Tweet

More Decks by Bob Majdak Jr

Other Decks in Programming

Transcript

  1. Introduction  Working with pictures is a must anymore to

    complete the whole social experience of the internet.  You will not memorize the API’s today. There are too many and they are full of weird.  Hopefully you get a feeling of knowing what you can/cannot do easy and know where to look to implement further.
  2. PHP Graphic Library Overview  GD  Imagick  GMagick

     Ignored because it is [just] a fork of Imagick with the design principles of never advancing API’s for sake of backwards compat. A noble goal but...  Could not find a working Windows build anyway.  Cairo  Vector graphics, neato stuff, but...  Not enough actual filled out documentation, so I haven’t really used it and I'd sound like a retard talking about it.  Exif  Not actually an image library. A JPEG meta data reading library. It cannot even write.
  3. GD Graphics Library  Graphics Draw Library  Originally GIF

    Draw.  Was unable to actually render GIF’s from 1999 to 2004 because the GIF license was revoked. In 2004 the GIF patent expired.  Has bindings for nearly every language [that matters] ever.  Not really worked on anymore. PHP maintains their copy that is how we get along with that.  Sort of a “Copy and Paste” based system.
  4. PHP GD Pro/Con Pros  Comes bundled with PHP. 

    Compiles anywhere first time.  Lightweight for lightweight work.  Most web hosts will have it. Cons  Cumbersome to do advanced work with.  OLD style API (pre-OOP) – Procedural  Larger jobs consume LOTS of resources.  Terribad at Alpha Channel (opacity)
  5. ImageMagick  ImageMagick is the utility. Imagick is the PHP

    binding.  Huge graphics library able to write support nearly any image format you could care to think of.  Basically, Photoshop for your CLI.  Layer based system.  Has support for OpenCL  Meaning, it can use your GPU to do stuff.
  6. Imagick Pro/Con Pros  Lots of advanced features.  Decent

    OOP interface. *  Does heavy lifting with ease. Cons  Arse and a half to compile the dependencies.  Method names a bit goofy. *
  7. The Server Important configuration options for uploading  PHP.INI 

    file_uploads = On  Enables uploads  upload_max_filesize = 10M  How large each file can be.  post_max_size = 10M  Technically this would limit you to files slightly less than 10M as there is other post data involved in the request taking up space.  max_file_uploads = 10  How many files per form.  Large uploads take time.  May want to set_time_limit() a higher value in the upload script if you are expecting huge stuffs.
  8. The Form  enctype is the only real key here.

     <form method=“post” enctype=“multipart/form-data” ...  File elements  <input type=“file” name=“something[]” />  Allows multiple files with ease.  $_FILES[‘something’][‘name’][\d+]
  9. The Upload $_FILES[‘derp’] Array ( [name] => Array ( [0]

    => hail__king_arthas_menethil.jpg [1] => zInfg.jpg [2] => f6Kik.jpg ) [type] => Array ( [0] => image/jpeg [1] => image/jpeg [2] => image/jpeg ) [tmp_name] => Array ( [0] => C:\Users\bob\AppData\Local\Temp\phpA18.tmp [1] => C:\Users\bob\AppData\Local\Temp\phpA19.tmp [2] => C:\Users\bob\AppData\Local\Temp\phpA1A.tmp ) [error] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [size] => Array ( [0] => 235038 [1] => 176960 [2] => 61551 ) )
  10. Opening and Saving Files with GD  GD is resource

    based, so you open a resource pointer and pass it to image functions.  GD is also limited in types, and the opening functions you use depend on the type of file it is. That means you have to check for JPEG, PNG, etc.  $img = imagecreatefromjpeg($filename);  imagecreatefrompng();  imagecreatefromgif();  ...  Error? if(!$img) { ... }  Saving has all the same issues, you have to use a function named for the type of file you want to save.  imagejpeg($img,$filename,$quality);  imagepng();  imagegif();  ...
  11. Opening and Saving Files with Imagick  Imagick is object

    oriented. You create one and you use its own methods to against it.  Imagick is smart about filetypes. One call to rule them all...  $img = new Imagick($filename);  Error? An exception is thrown so you you can tryblock it.  Saving is just as smart. If the filename ends in .jpg, you get a JPEG file.  $img->writeImage($filename);
  12. Getting Image Size Handy to have laying around for the

    maths later  There is getimagesize() which is said to work without GD. Returns an array of various graphic data.  Also returns mime type as part of the array so you could use it for “is this an image” checking. Here I only care about the size as we already opened images on the last two slides.  list($imgw,$imgh) = getimagesize($filename);  GD  $imgw = imagesx($img);  $imgh = imagesy($img);  Imagick  $imgw = $img->getImageWidth();  $imgh = $img->getImageHeight();
  13. Closing Files / Freeing Resources  In both cases, we

    need to free system resources when we are done with an image.  You will quickly run into memory limit issues if you fail to free your resources when you are done using them.  GD  imagedestroy($img);  unset($img);  Imagick  $img->destroy();  unset($img);
  14. Pseudocode [startup] for later examples. Assuming an always valid JPEG

    file for the examples - Open and Size Up. GD $img = imagecreatefromjpeg($filename); $imgw = imagesx($img); $imgh = imagesy($img); Imagick $img = new Imagick($filename); $imgw = $img->getImageWidth(); $imgh = $img->getImageHeight(); Pseudocode [shutdown] for later examples. Assuming an always valid image resource - Save and Free. imagejpeg($img,$filename,100); imagedestroy($img); unset($img); $img->writeImage($filename); $img->destroy(); unset($img);
  15. Basic Geometric Tasks  Cropping  Resizing  Scaling 

    Thumbnailing  GD  imagecopyresampled  We use this with different maths to do it all.  Imagick  cropImage  resizeImage  thumbnailImage
  16. Cropping  Cutting an image smaller than it already is,

    much like cutting a picture out of the newspaper or magazine.  Need to know:  X and Y of top corner.  W and H of desired cut.
  17. Cropping Images – GD Crop a 200px square, 100px from

    the top corner. [startup] // a new blank image buffer to copy to. $new = imagecreatetruecolor(200,200); imagecopyresampled( $new, // destination buffer $img, // source buffer 0, 0, // destination x,y 100, 100, // source region top left x,y 200, 200, // destination w,h 200, 200 // source region w,h ); imagedestroy($img); $img = $new; unset($new); [shutdown]
  18. Cropping Images – Imagick Crop a 200px square, 100px from

    the top corner. [startup] $img->cropImage( 200, 200, // region w,h 100, 100 // region top left corner x,y ); [shutdown]
  19. Resizing  Changing the Width and Height of an image

    to be a new Width and Height.  Aspect ratio? Honey badger don’t care.  Need to know:  Desired W and H
  20. Resizing Images – GD Force image into a 200x100 pixel

    shape [startup] $new = imagecreatetruecolor(200,100); imagecopyresampled( $new, // destination buffer $img, // source buffer 0, 0, // destination x,y 0, 0, // source region x,y 200, 100, // destination w,h $imgw, $imgh // source region w, h ); imagedestroy($img); $img = $new; unset($new); [shutdown]
  21. Resizing Images – Imagick Force image into a 200x100 pixel

    shape [startup] $img->resizeImage( 200, 200, Imagick::FILTER_LANCZOS, 1 ); [shutdown]
  22. Scaling  Fit an image inside of a size but

    keep the aspect ratio intact.  One dimension will be smaller than the requested size, unless it was a perfect square and you asked for a perfect square.  Same as resize code but with an added magical function for maths. This function would check if the image is tall or wide, and then do the proportion math to give the final size.  Need to know:  W and H of image  W and H you want to fit it in
  23. Scaling Images – GD Fit the image to be less

    than or equal to 200x200 [startup] list($nw,$nh) = bob_magic_proportion_func( $imgw, $imgh, // source size 200, 200 // desired max size ); $new = imagecreatetruecolor($nw,$nh); imagecopyresampled( $new, // destination buffer $img, // source buffer 0, 0, // destination x,y 0, 0, // source region x,y $nw, $nh, // destination w,h $imgw, $imgh // source region w, h ); imagedestroy($img); $img = $new; unset($new); [shutdown]
  24. Scaling Images – Imagick Fit the image to be less

    than or equal to 200x200 [startup] $img->resizeImage( 200, 200, Imagick::FILTER_LANCZOS, 1, true ); [shutdown]
  25. Thumbnailing  Creating a useful representation that is fill fit

    to a size, then with the excess cropped off.  Fill fit to the smallest dimension.  Crop excess in longest dimension.  For demo simplicity, our resulting image is a perfect square.  Need to know:  W and H of image  W and H of desired thumbnail
  26. Thumbnailing Images – GD Create a scaled, centered, cropped, 200x200

    thumbnail [startup] if($imgw > $imgh) list($nw,$nh) = bob_magic_proportion_func($imgw,$imgh,-1,200); else list($nw,$nh) = bob_magic_proportion_func($imgw,$imgh,200,-1); // scale it down to the calculated size. $new = imagecreatetruecolor($nw,$nh); imagecopyresampled($new,$img,0,0,0,0,$nw,$nh,$imgw,$imgh); imagedestroy($img); unset($img); // crop off the excess from either end to center it and fit it $last = imagecreatetruecolor(200,200); imagecopyresampled( $last, $new, 0, 0, ($nw / 2) – (200 / 2), ($nh / 2) – (200 / 2), 200, 200, 200, 200 ); imagedestroy($new); unset($new); $img = $last; unset($last); [shutdown]
  27. Thumbnailing Images – Imagick Create a scaled, centered, cropped, 200x200

    thumbnail [startup] $img->thumbnailImage(200,200); [shutdown]
  28. Basic ‘Shoopin Shoop da woop  Desaturation  Sepia 

    Lots of other filters, but they are all more or less repetitive.  Watermarking  GD  imagefilter  imagecopyresampled  Imagick  modulateImage  sepiaToneImage  compositeImage
  29. Filters Almost over 9,000 GD  Negative  Greyscale 

    Brightness  Contrast  Colorize  Edge  Emboss  Blur  Sketch  Pixelate Imagick  Blur  3 Different Kinds  Brightness  Charcoal  Combine  Colorize  Color Replace  Distort  Enhance  Equalize  Flop  Frame  Gamma  Hue Shift  Level  Magnify  Median Filter  Modulate  Normalize  Oil Paint  Posturize  Rolling  Round corners  Sepia  Shade  Sharpen  Solarize  Stegano  Swirl  Texturize  Vignette
  30. Desaturate Images Black and white photographs GD [startup] imagefilter( $img,

    IMG_FILTER_GRAYSCALE ); [shutdown] Imagick [startup] $img->modulateImage( 100, // brightness 0, // saturation 100 // hue shift ); [shutdown]
  31. Sepia Tone Images Old photo aged photograph GD [startup] imagefilter(

    $img, IMG_FILTER_GRAYSCALE ); imagefilter( $img, IMG_FILTER_COLORIZE, 90, // red 40, // green 3 // blue ); [shutdown] Imagick [startup] $img->sepiaToneImage(80); [shutdown]
  32. Watermarking Overlaying a ghost image on an image. GD [startup]

    $mark = imagefrompng($markfile); $markw = imagesx($mark); $markh = imagesy($mark); imagefilter( $mark, IMG_FILTER_GRAYSCALE ); imagecopyresampled( $img, $mark, ($imgw - $markw), ($imgh - $markh), 0, 0, $markw, $markh, $markw, $markh ); imagedestroy($mark); [shutdown] Imagick [startup] $mark = new Imagick($markfile); $x = $img->getImageWidth()-$mark->getImageWidth(); $y = $img->getImageHeight()-$mark->getImageHeight(); $mark->modulateImage(100,0,100); $img->compositeImage( $mark, Imagick::COMPOSITE_DEFAULT, $x, $y ); $mark->destroy(); [shutdown]
  33. How they handle drawing. GD  Draw directly on to

    the image resource you want to draw on.  Fast.  Super easy if you do not need anything too involved. Imagick  Draw on a special “draw layer” and then lay it on top of the image.  Great for advanced drawing. Not as easy.
  34. Drawing Shapes Drawing an ellipse over the entire image. GD

    [startup] $red = imagecolorallocate($img,255,0,0); imagefilledellipse( $img, floor($imgw/2), floor($imgh/2), $imgw, $imgh, $red ); [shutdown] Imagick [startup] $draw = new ImagickDraw; $draw->setFillColor( new ImagickPixel(‘red’) ); $draw->ellipse( floor($imgw/2), floor($imgh/2), floor($imgw/2), floor($imgh/2), 0, 360 ); $img->drawImage($draw); $draw->destroy(); [shutdown]
  35. Writing Text on an Image Fonts are tricksy  Both

    Imagick and GD are suppose to have the ability to use the fonts installed on the system.  Except that works 0 times out of 10.  What does work? Absolute path to a font (TTF) file. That always works, in both libraries.  Font sizes: GD Points, Imagick Pixels. Derp.  PHP manual says Imagick is points too, but my own observations + other people say it is wrong.
  36. Writing Text on an Image – GD Apply directly to

    the forehead. GD [startup] $color = imagecolorallocate($img,255,0,0); imagettftext( $img, $size, $angle, $x, $y, $color, $fontfile, $text ); [shutdown]
  37. Writing Text on an Image – Imagick Sort of works

    like an old typewriter. Really. Imagick [startup] $color = new ImagickPixel(‘red’); $draw = new ImagickDraw; $draw->setFont($fontfile); $draw->setFontSize($size); $draw->setFillColor($color); $img->annotateImage( $draw, $x, $y, $angle, $text ); $draw->destroy(); [shutdown]
  38. So, You’re punching pixels in the face? Image processing is

    slow (relative to, say, a PING).  Try to avoid doing large image processing during a request, if possible.  Something goofy like cropping a user avatar? That’s something that is OK to do live.  Leaving the webserver and request hanging to render a 8 megapixel subway map is not.  How and when you process is something you have to think about how your app works.
  39. Still pixel punching? I know, those little guys never give

    up. Punch harder.  The larger your images are, the more RAM you will need to allow PHP to use.  memory_limit=300M  You are probably looking at a value around this if your users are uploading photos off their new smarty telephones for you to scale down to web size.  memory_limit=2G  And this is what you are looking at if you are going to try stuff like this...
  40. Doing something HUGE because I can Daniel said I was

    crazy. Daniel doesn’t even know. I can see you Daniel. 15306x7653 pixel map of the earth. 3650 long/lat points to plot. GD  3.5sec to open  3.3sec to desaturate  0.05sec to plot  6sec to write JPEG to disk. 11.1MB  74sec to write PNG to disk. 46.1MB.  Peak RAM use: 1,043 MB Imagick  3sec  1.5sec to desaturate  1sec to plot  0.4sec plot “done right”  4.5sec to write JPEG to disk. 9.4MB  30sec to write PNG to disk. 46.3MB  Peak RAM use: 450 MB
  41. Performance Summary  Small images, lots of drawing? GD. 

    Small images, lots of filtering? Imagick.  Large images, doing anything? Ehh eh. Well. Imagick would probably be your best bet to try first.  Imagick if you value your alpha channel.
  42. The End Twitter: @bobmajdakjr Email: [email protected] Blog: http://catch404.net This entire

    codebase (demo site, apps, libraries) on Github. https://joind.in/6339 https://github.com/bobmajdakjr/dall asphp-image-tools-code