Created
December 19, 2012 03:12
-
-
Save jnrbsn/4334075 to your computer and use it in GitHub Desktop.
Calculates the "busiest" square area of an image to use for a thumbnail.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* An example of how to use the `squarize()` function below. | |
*/ | |
$path_input = 'input.png'; | |
$path_output = 'output.png'; | |
$thumb_w = 100; | |
$thumb_h = 100; | |
$input = imagecreatefrompng($path_input); | |
$output = imagecreatetruecolor($thumb_w, $thumb_h); | |
list($crop_x, $crop_y, $crop_w, $crop_h) = squarize($source); | |
imagecopyresampled($output, $input, 0, 0, $crop_x, $crop_y, $thumb_w, $thumb_h, $crop_w, $crop_h); | |
imagepng($output, $path_output, 9); | |
imagedestroy($input); | |
imagedestroy($output); | |
/** | |
* Calculates the "busiest" square area of an image to use for a thumbnail. | |
* | |
* Samples a grid of pixels from an image, calculates the standard deviation of the RGB values of | |
* those pixels, and returns information about the biggest square area of the image with the largest | |
* standard deviation of colors (i.e. the "busiest" part of the image). | |
* | |
* @param resource $img A GD image link resource. | |
* @param integer $width The width of the source image (optional). | |
* @param integer $height The height of the source image (optional). | |
* @param integer $pixels The distance between each pixel to sample (default: 10). | |
* | |
* @return array An array containing the x-coordinate of the top left corner of the crop area, the | |
* y-coordinate of the top left corner of the crop area, the width of the crop area, | |
* and the height of the crop area. | |
*/ | |
function squarize($img, $width = null, $height = null, $pixels = 10) | |
{ | |
if ($width === null || $height === null) { | |
$width = imagesx($img); | |
$height = imagesy($img); | |
} | |
$rgb = array(); | |
for ($x = 0; $x < $width; $x += $pixels) { | |
for ($y = 0; $y < $height; $y += $pixels) { | |
$color = imagecolorat($img, $x, $y); | |
$rgb[$x][$y] = array(($color >> 16) & 0xFF, ($color >> 8) & 0xFF, $color & 0xFF); | |
} | |
} | |
$dev_max = 0; | |
$diff = abs($height - $width); | |
$x_bound = array(0, $width); | |
$y_bound = array(0, $height); | |
$count = pow((int)(min($height, $width) / $pixels), 2); | |
for ($i = 0, $r = 0, $g = 0, $b = 0, $dev = 0; $i < $diff; $i += $pixels) { | |
if ($height > $width) { | |
$y_bound = array($i, $width + $i); | |
} elseif ($height < $width) { | |
$x_bound = array($i, $height + $i); | |
} | |
for ($x = $x_bound[0]; $x < $x_bound[1]; $x += $pixels) { | |
for ($y = $y_bound[0]; $y < $y_bound[1]; $y += $pixels) { | |
$r += $rgb[$x][$y][0]; | |
$g += $rgb[$x][$y][1]; | |
$b += $rgb[$x][$y][2]; | |
} | |
} | |
$r /= $count; | |
$g /= $count; | |
$b /= $count; | |
for ($x = $x_bound[0]; $x < $x_bound[1]; $x += $pixels) { | |
for ($y = $y_bound[0]; $y < $y_bound[1]; $y += $pixels) { | |
$tmp = ($rgb[$x][$y][0] - $r) * ($rgb[$x][$y][0] - $r); | |
$tmp += ($rgb[$x][$y][1] - $g) * ($rgb[$x][$y][1] - $g); | |
$tmp += ($rgb[$x][$y][2] - $b) * ($rgb[$x][$y][2] - $b); | |
$dev += sqrt($tmp); | |
} | |
} | |
$dev /= $count; | |
if ($dev > $dev_max) { | |
$dev_max = $dev; | |
$crop_x = $x_bound[0]; | |
$crop_y = $y_bound[0]; | |
} | |
} | |
$crop_w = min($width, $height); | |
$crop_h = $crop_w; | |
return array($crop_x, $crop_y, $crop_w, $crop_h); | |
}//end squarize() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment