📜 ⬆️ ⬇️

Creating Instagram Filters with PHP and ImageMagick

image

In this article, I will show how to create some effects on photos (like on Instagram) using PHP and ImageMagick.

Image Processing with PHP


PHP comes bundled with GD (GIF Draw / Graphics Draw). It is used for simple operations with images, such as resizing, cropping, adding watermarks, creating thumbnails. Unfortunately, if you want to create something more complex with GD it will not work. Fortunately, we have ImageMagick!
')
GD vs. Imagemagick


Let's look at the image resize example.

GD:

$im = imagecreatefromjpeg('photo.jpg'); $ox = imagesx($im); $oy = imagesy($im); $nx = 640; $ny = 480; $nm = imagecreatetruecolor($nx, $ny); imagecopyresized($nm,$im,0,0,0,0,$nx,$ny,$ox,$oy); imagejpeg($nm, 'photo.jpg'); 


ImageMagick:

IM (abbreviated from ImageMagick) has a good shell, called Imagick - a native PHP extension for creating and editing images using the ImageMagick API. The only disadvantage is that it is installed from PECL , which can sometimes be a problem for shared hosting.

 $image = new Imagick('photo.jpg'); $image->resizeImage(640, 480, imagick::FILTER_LANCZOS, 0.9); 


And using the command line is even easier:

 exec('mogrify -resize 640x480 photo.jpg'); 


Install ImageMagick


Click on the link , select the platform (Unix / Mac / Win) and select the recommended package.

After the installation is completed, go to the terminal / command line, enter convert and press Enter, if you get a list of options, not “Command not found”, then everything is fine! Please note that you do not need to configure anything in PHP.

Instagraph - PHP class


I created a small PHP class script to make filtering images as simple as possible.
  1. colortone: The will of the color tone of the image in highlights and / or shadow.
  2. vignette: the edges of the image are discolored.
  3. border: adds borders to a photo.
  4. frame: will read the specified frame according to the photo.
  5. tempfile: creates a temporary file (copy of the original image).
  6. output: rename work file
  7. execute: send command


Create a new file named instagraph.php and paste the following code.

 /** * Instagram filters with PHP and ImageMagick * * @package Instagraph * @author Webarto <dejan.marjanovic@gmail.com> * @copyright NetTuts+ * @license http://creativecommons.org/licenses/by-nc/3.0/ CC BY-NC */ class Instagraph { public $_image = NULL; public $_output = NULL; public $_prefix = 'IMG'; private $_width = NULL; private $_height = NULL; private $_tmp = NULL; public static function factory($image, $output) { return new Instagraph($image, $output); } public function __construct($image, $output) { if(file_exists($image)) { $this->_image = $image; list($this->_width, $this->_height) = getimagesize($image); $this->_output = $output; } else { throw new Exception('File not found. Aborting.'); } } public function tempfile() { # copy original file and assign temporary name $this->_tmp = $this->_prefix.rand(); copy($this->_image, $this->_tmp); } public function output() { # rename working temporary file to output filename rename($this->_tmp, $this->_output); } public function execute($command) { # remove newlines and convert single quotes to double to prevent errors $command = str_replace(array("\n", "'"), array('', '"'), $command); $command = escapeshellcmd($command); # execute convert program exec($command); } /** ACTIONS */ public function colortone($input, $color, $level, $type = 0) { $args[0] = $level; $args[1] = 100 - $level; $negate = $type == 0? '-negate': ''; $this->execute("convert {$input} ( -clone 0 -fill '$color' -colorize 100% ) ( -clone 0 -colorspace gray $negate ) -compose blend -define compose:args=$args[0],$args[1] -composite {$input}"); } public function border($input, $color = 'black', $width = 20) { $this->execute("convert $input -bordercolor $color -border {$width}x{$width} $input"); } public function frame($input, $frame) { $this->execute("convert $input ( '$frame' -resize {$this->_width}x{$this->_height}! -unsharp 1.5×1.0+1.5+0.02 ) -flatten $input"); } public function vignette($input, $color_1 = 'none', $color_2 = 'black', $crop_factor = 1.5) { $crop_x = floor($this->_width * $crop_factor); $crop_y = floor($this->_height * $crop_factor); $this->execute("convert ( {$input} ) ( -size {$crop_x}x{$crop_y} radial-gradient:$color_1-$color_2 -gravity center -crop {$this->_width}x{$this->_height}+0+0 +repage ) -compose multiply -flatten {$input}"); } /** RESERVED FOR FILTER METHODS */ } 


Let's see what happens


Original image:

image

Gotham filter

Gotham filter brings the image to black and white. High contrast images with a bluish tint.

 public function gotham() { $this->tempfile(); $this->execute("convert $this->_tmp -modulate 120,10,100 -fill '#222b6d' -colorize 20 -gamma 0.5 -contrast -contrast $this->_tmp"); $this->border($this->_tmp); $this->output(); } 




Filter toaster

Reminds old pictures of Polaroid, it has bright colors along with a pink / orange glow from the center. According to the Instagram CEO, this is one of the most complex effects.
 public function toaster() { $this->tempfile(); $this->colortone($this->_tmp, '#330000', 100, 0); $this->execute("convert $this->_tmp -modulate 150,80,100 -gamma 1.2 -contrast -contrast $this->_tmp"); $this->vignette($this->_tmp, 'none', 'LavenderBlush3'); $this->vignette($this->_tmp, '#ff9966', 'none'); $this->output(); } 


You can even add a white frame for the full effect, just add

 $this->border($this->_tmp, 'white');  $this->output(); 




Nashville Filter

 public function nashville() { $this->tempfile(); $this->colortone($this->_tmp, '#222b6d', 100, 0); $this->colortone($this->_tmp, '#f7daae', 100, 1); $this->execute("convert $this->_tmp -contrast -modulate 100,150,100 -auto-gamma $this->_tmp"); $this->frame($this->_tmp, __FUNCTION__); $this->output(); } 




Lomo filter

 public function lomo() { $this->tempfile(); $command = "convert {$this->_tmp} -channel R -level 33% -channel G -level 33% $this->_tmp"; $this->execute($command); $this->vignette($this->_tmp); $this->output(); } 




Kelvin filter

 public function kelvin() { $this->tempfile(); $this->execute("convert ( $this->_tmp -auto-gamma -modulate 120,50,100 ) ( -size {$this->_width}x{$this->_height} -fill 'rgba(255,153,0,0.5)' -draw 'rectangle 0,0 {$this->_width},{$this->_height}' ) -compose multiply $this->_tmp"); $this->frame($this->_tmp, __FUNCTION__); $this->output(); } 




How to use it?


I assume that you saved all the code in the instagraph.php file. Now create a file called filter.php and copy the following code.

If you want to apply only one filter, you can do it as follows:

 require 'instagraph.php'; try { $instagraph = Instagraph::factory('input.jpg', 'output.jpg'); } catch (Exception $e) { echo $e->getMessage(); die; } $instagraph->toaster(); //   


That's all! If you want to apply all filters use this code:

 require 'instagraph.php'; try { $instagraph = Instagraph::factory('input.jpg', 'output.jpg'); } catch (Exception $e) { echo $e->getMessage(); die; } // loop through all filters foreach(array('gotham', 'toaster', 'nashville', 'lomo', 'kelvin') as $method) { $instagraph->_output = $method.'.jpg'; // we have to change output file to prevent overwrite $instagraph->$method(); // apply current filter (from array) } 


Performance


Performance is certainly an important part in any application. Applying a filter to an image takes about 1 second, we can say with confidence that it is very fast!

Source: https://habr.com/ru/post/140704/


All Articles