Tenemos dentro una carpeta una serie de imágenes con distinta relación de aspecto (o ratio de aspecto, o aspect ratio en inglés) y distinto tamaño. El objetivo es recortar (crop) las fotos en la medida que sea necesario para lograr que todas las imágenes tengan una misma relación de aspecto indicada
Un script en PHP que calcula en base a la dimensión de la imagen cuanto y donde es necesario cortar para obtener una relación de aspecto determinada. Con esta información, se construyen las opciones al comando convert que se ejecuta posteriormente utilizando exec.
<?php
if (count($_SERVER['argv']) < 3) {
print "Usage\n";
print " " . $_SERVER['SCRIPT_FILENAME'] . " input output ratio\n";
exit();
}
define("DIR",$_SERVER['argv'][1]);
define("DIROUT",$_SERVER['argv'][2]);
define("RATIO",$_SERVER['argv'][3]);
$input = realpath(DIR);
$output = realpath(DIROUT);
$fraction = explode("/", RATIO);
if (count($fraction) == 1) {
$ratio = RATIO;
} else {
$ratio = $fraction[0]/$fraction[1];
}
print $ratio."\n";
if (!$handle = opendir($input)) {
print "Can't open input directory: " . DIR . "\n";
return;
}
$objects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($input),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($objects as $file => $object) {
// handle only jpg files
if (pathinfo($file, PATHINFO_EXTENSION) != 'jpg') {
continue;
}
// get image size
$img_info = array();
exec("convert " . escapeshellarg($file) . " -print \"%w,%h\" /dev/null", $img_info);
$img_size = explode(",", $img_info[0]);
$img_w = $img_size[0];
$img_h = $img_size[1];
// tall or wide?
if ($img_w >= $img_h) {
$img_ratio = $img_w/$img_h;
$min = "img_h";
$max = "img_w";
} else {
$img_ratio = $img_h/$img_w;
$min = "img_w";
$max = "img_h";
}
// crop and offset
if ($img_ratio < $ratio) {
$var = "new_".$max;
$$var = $$max;
$var2 = "new_".$min;
$$var2 = round($$var/$ratio);
} else {
$var = "new_".$min;
$$var = $$min;
$var_new_max = "new_".$max;
$$var_new_max = round($$var*$ratio);
}
// create output directory
$output_path = $output . substr($file, strlen($input));
if (!file_exists(dirname($output_path))) {
mkdir(dirname($output_path));
}
$cmd = "convert -quality 90 " . escapeshellarg($file);
$cmd .= " -crop {$new_img_w}x{$new_img_h}+";
$cmd .= abs(floor((intval($img_w) - intval($new_img_w)) / 2)). "+";
$cmd .= floor((intval($img_h) - intval($new_img_h)) / 2);
$cmd .= " +repage " . escapeshellarg($output_path);
print "\nconvert " . pathinfo($file, PATHINFO_BASENAME). "\n";
print " from: {$img_w} x {$img_h}\n";
print " to: {$new_img_w} x {$new_img_h}\n";
exec($cmd);
}
closedir($handle);
Vamos con un ejemplo: Para modificar el ratio a 16/9 de todas las imágenes dentro input y guardarlas dentro el directorio output:
php script.php input output 16/9