Skip to content

Instantly share code, notes, and snippets.

@timo-schmid
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timo-schmid/1896406008df169d1461 to your computer and use it in GitHub Desktop.
Save timo-schmid/1896406008df169d1461 to your computer and use it in GitHub Desktop.
Functional image crop in PHP with GD
<?php
/**
* Functional approach of automatic image cropping, pass a file path and a color callback, which evaluates if a color is below the crop threshold or not.
* @param $path The path to the file
* @param $colorFilter Clojure, the function takes 1 parameter: $color is the hex value of the color to evaluate
* Code Example:
* <code>
* $newImg = $imageAutocrop($path, function($color) { return $color > 0xF0FFFF || $color === 0;});
* </code>
*/
$imageAutocrop = function($path, $colorFilter) {
if(!file_exists($path)) {
throw new Exception("File not found.");
}
$size = getimagesize($path);
if(!$size) {
throw new Exception("Not an image: $path");
}
switch($size["mime"]){
case "image/jpeg":
$img = imagecreatefromjpeg($path); //jpeg file
break;
case "image/gif":
$img = imagecreatefromgif($path); //gif file
break;
case "image/png":
$img = imagecreatefrompng($path); //png file
break;
default:
$img = false;
break;
}
if(!$img) {
throw new Exception('Given file is not a valid image.');
}
/**
* Inner function, used to search for the offsets to crop at.
* @param $img The GD resource
* @param $colorFilter The callback to evaluate colors
* @param $h The height of the image
* @param $w The width of the image
* @param $xFn Callback to calculate the X-Coordinate to search for each point
* @param $yFn Callback to calculate the Y-Coordinate to search for each point
*/
$getOffset = function($img, $colorFilter, $h, $w, $xFn, $yFn) {
for($y = 0;$y < $h;$y++) {
for($x = 0;$x < $w;$x++) {
$c = imagecolorat($img, $xFn($w, $h, $x, $y), $yFn($w, $h, $x, $y));
if(!$colorFilter($c)) {
return $y;
}
}
}
};
$h = imagesy($img);
$w = imagesx($img);
$offsetTop = $getOffset($img, $colorFilter, $h, $w, function($w, $h, $x, $y) { return $x; }, function($w, $h, $x, $y) { return $y; });
$offsetBottom = $getOffset($img, $colorFilter, $h, $w, function($w, $h, $x, $y) { return $w - 1 - $x; }, function($w, $h, $x, $y) { return $h - 1 - $y; });
$offsetLeft = $getOffset($img, $colorFilter, $w, $h, function($w, $h, $x, $y) { return $y; }, function($w, $h, $x, $y) { return $x; });
$offsetRight = $getOffset($img, $colorFilter, $w, $h, function($w, $h, $x, $y) { return $w - 1 - $y; }, function($w, $h, $x, $y) { return $h - 1 - $x; });
$newH = $h - ($offsetTop + $offsetBottom);
$newW = $w - ($offsetLeft + $offsetRight);
$newImg = imagecreatetruecolor($newW, $newH);
imagecopy($newImg, $img, 0, 0, $offsetLeft, $offsetTop, $newW, $newH);
return $newImg;
};
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment