function focal_point_smartcrop_estimation in Focal Point 7
Given an image, use smartcrop to estimate a good focal point.
See also
http://envalo.com/image-cropping-php-using-entropy-explained/
1 call to focal_point_smartcrop_estimation()
- focal_point_get_smartcrop_focal_point in ./
focal_point.module - Callback function.
File
- ./
focal_point.smartcrop.inc, line 20
Code
function focal_point_smartcrop_estimation(stdClass $image_data) {
// To avoid bad performance with large images, we calculate the focal point on
// a smaller version of the image. 500px should be far enough.
// @todo Consider making this configurable.
static $px_needed = 500;
$image_data = clone $image_data;
// If the current image toolkit is ImageMagick, GD resource has to be
// populated.
if (image_get_toolkit() != 'gd') {
image_gd_load($image_data);
}
$image_width = $image_data->info['width'];
$image_height = $image_data->info['height'];
$ratio = max($px_needed / $image_width, $px_needed / $image_height);
$resized = FALSE;
if ($ratio <= 1) {
$resized = image_gd_resize($image_data, round($ratio * $image_width), round($ratio * $image_height));
}
$full_width = imagesx($image_data->resource);
$full_height = imagesy($image_data->resource);
// Given that most of the time, cropped images have a width/height ratio
// between 4:1 and 1:4, the width of a cropped image will be greater than
// (original height)/4 and the height greater than (original width)/4.
// Based on this assumption, we will try to find the most interesting area
// (max entropy) of this size.
// The focal point will simply be the center of the resulting area.
// @todo Consider making this configurable.
static $highest_ratio = 4;
static $largest_ratio = 4;
$target_width = round($full_height / $highest_ratio);
$target_height = round($full_width / $largest_ratio);
// First, we will cut our image into 25 vertical and horizontal slices, to get
// 25x25 areas, then calculate their entropy.
// @todo Consider making this configurable.
static $slices_count = 25;
$area_width = $full_width / $slices_count;
$area_height = $full_height / $slices_count;
$area_entropies = array();
for ($i = 0; $i < $slices_count; $i++) {
$area_entropies[$i] = array();
for ($j = 0; $j < $slices_count; $j++) {
$area_entropies[$i][$j] = _smartcrop_gd_entropy_slice($image_data, round($i * $area_width), round($j * $area_height), $area_width, $area_height);
}
}
// We calculate how many areas are needed to get the target width and height.
$target_areas_counts = array(
ceil(min($target_width / $area_width, $slices_count)),
ceil(min($target_height / $area_height, $slices_count)),
);
// We get the adjacent areas that lead to the maximum entropy.
$best_first_area = _focal_point_smartcrop_get_best_first_area($area_entropies, $target_areas_counts);
// We calculate the middle of the resulting area.
$x = $area_width * ($best_first_area[0] + $target_areas_counts[0] / 2);
$y = $area_height * ($best_first_area[1] + $target_areas_counts[1] / 2);
if ($resized) {
// We return the center of the resulting area, but for the original image,
// not the small one.
$x = $x / $ratio;
$y = $y / $ratio;
}
return array(
round($x),
round($y),
);
}