Hace unos dรญas hemos hecho una pรกgina web para un cliente en Prestashop. Este cliente, tenรญa la peculiaridad (respecto a clientes anteriores) que disponรญa de unas imรกgenes con buena calidad. Al subirlas a Prestashop, tanto en la subida por producto, como en la importaciรณn masiva, la pรฉrdida de calidad era mรกs que evidente. Las fotos de Prestashop no tenรญan una calidad aceptable teniendo en cuenta las fotos de origen. Y en esa pรกgina, las imรกgenes eran clave.
La pรกgina la hemos creado en 1.7, pero lo probamos en 1.6 y el resultado era el mismo. Calidad muy por debajo de lo aceptable cuando las imรกgenes originales son de calidad (para imรกgenes “usuales” si que es funcional).
Obviamente modificamos todas las opciones de calidad en el backend de Prestashop ( Diseรฑo >ย Ajustes de imรกgenes ), sin mejora importante del resultado.
Nos somos a los primeros a los que les pasรณ (ver aquรญ y aquรญ). Es un tema recurrente y sin resolver (“sorpresa” por parte de Prestashop).
Al final descubrimos por quรฉ y cรณmo resolverlo. Os lo contamos en este artรญculo.
Cรณmo mejorar la calidad de las imรกgenes que se suben o se importan en Prestashop.
Lo primero es la causa que ocasiona esta pรฉrdida de calidad. Prestashop comprime todas las imรกgenes al subirlas. Y crea varias imรกgenes de diferentes tamaรฑos (que se definen en Diseรฑo >ย Ajustes de imรกgenesย ). Esto es lรณgico y bueno. El problema es que usa un mรฉtodo de compresiรณn,ย GD2, que antes se usaba mucho por estar integrado en Php (o en la mayorรญa de las instalaciones). Sin embargo no es la librerรญa que mejores resultados da, tiene pocas opciones y, ademรกs, creo que Php 7 ya no la incluye por defecto.
Despuรฉs de varias pruebas infructuosas con GD, optamos por cambiar a Imagemagick siguiendo las indicaciones de un post al que enlazamos en los pรกrrafos anteriores.
Siguiendo los resultados arreglaba algo la subida producto a producto, pero no la masiva. Y aรบn asรญ, no conseguรญamos los mejores resultados asรญ que modificamos el proceso para lo que querรญamos. Esto es lo que hicimos..
Para las subidas desde el backend.
Tenemos que:
- Hacer un override (copiar en la carpeta override/classes) de la clase ImageManager.php porque queremos modificar la funciรณn resize para que use ImageMagick.
Nota:ย Para esto tu servidor tiene que tener ImageMagick o deberรญas poder instalarlo. Si no no funciona. - En ese ficheroย ย override/classes/ImageManager.php ponemos lo siguiente:
<?php
class ImageManager extends ImageManagerCore
{/**
* Resize, cut and optimize image
*
* @param string $src_file Image object from $_FILE
* @param string $dst_file Destination filename
* @param int $dst_width Desired width (optional)
* @param int $dst_height Desired height (optional)
* @param string $file_type
* @param bool $force_type
* @param int $error
* @param int $tgt_width
* @param int $tgt_height
* @param int $quality
* @param int $src_width
* @param int $src_height
* @return bool Operation result
*/
public static function resize2($src_file, $dst_file, $dst_width = null, $dst_height = null, $file_type = ‘jpg’,
$force_type = false, &$error = 0, &$tgt_width = null, &$tgt_height = null, $quality = 5,
&$src_width = null, &$src_height = null)
{
if (PHP_VERSION_ID < 50300) {
clearstatcache();
} else {
clearstatcache(true, $src_file);
}if (!file_exists($src_file) || !filesize($src_file)) {
return !($error = self::ERROR_FILE_NOT_EXIST);
}list($src_width, $src_height, $type) = getimagesize($src_file);
// If PS_IMAGE_QUALITY is activated, the generated image will be a PNG with .jpg as a file extension.
// This allow for higher quality and for transparency. JPG source files will also benefit from a higher quality
// because JPG reencoding by GD, even with max quality setting, degrades the image.
if (Configuration::get(‘PS_IMAGE_QUALITY’) == ‘png_all’
|| (Configuration::get(‘PS_IMAGE_QUALITY’) == ‘png’ && $type == IMAGETYPE_PNG) && !$force_type) {
$file_type = ‘png’;
}if (!$src_width) {
return !($error = self::ERROR_FILE_WIDTH);
}
if (!$dst_width) {
$dst_width = $src_width;
}
if (!$dst_height) {
$dst_height = $src_height;
}$width_diff = $dst_width / $src_width;
$height_diff = $dst_height / $src_height;$ps_image_generation_method = Configuration::get(‘PS_IMAGE_GENERATION_METHOD’);
if ($width_diff > 1 && $height_diff > 1) {
$next_width = $src_width;
$next_height = $src_height;
} else {
if ($ps_image_generation_method == 2 || (!$ps_image_generation_method && $width_diff > $height_diff)) {
$next_height = $dst_height;
$next_width = round(($src_width * $next_height) / $src_height);
$dst_width = (int)(!$ps_image_generation_method ? $dst_width : $next_width);
} else {
$next_width = $dst_width;
$next_height = round($src_height * $dst_width / $src_width);
$dst_height = (int)(!$ps_image_generation_method ? $dst_height : $next_height);
}
}if (!ImageManager::checkImageMemoryLimit($src_file)) {
return !($error = self::ERROR_MEMORY_LIMIT);
}//Set Imagick Object values
/* $src_image = new Imagick();
$src_image->readImage($src_file);
$src_image->setImageCompression(Imagick::COMPRESSION_JPEG);
$src_image->setInterlaceScheme(Imagick::INTERLACE_PLANE);
$src_image->setImageCompressionQuality(89);
$src_image->sharpenimage(2, 0.5, 134217727);
$src_image->gaussianBlurImage(0.03,0.03);
$src_image->stripImage();
$src_image->thumbnailImage($dst_width, $dst_height, Imagick::FILTER_SINC, 1);*/
$src_image = new Imagick();
$src_image->readImage($src_file);
$src_image->setImageCompression(Imagick::COMPRESSION_JPEG);
/*$src_image->setImageFormat(‘png’);*/
/*$src_image->setInterlaceScheme(Imagick::INTERLACE_PLANE);*/
$src_image->setImageCompressionQuality(89);
/*$src_image->sharpenimage(1.5, 0.5, Imagick::CHANNEL_ALL);*/
/* $src_image->gaussianBlurImage(0.03,0.03);*/
$src_image->stripImage();
$src_image->thumbnailImage($dst_width, $dst_height, Imagick::FILTER_LANCZOS, 1);
$src_image->brightnessContrastImage(1,0,Imagick::CHANNEL_ALL);
$src_image->gammaImage(0.9,Imagick::CHANNEL_ALL);
$src_image->modulateImage(100,120,100);
//Output the final Image using Imagick
return $src_image->writeImage($dst_file);}
}
Como veis hemos creado la funciรณn resize2 que usarรก ImageMagick. Dejando el nombre resize arregla el backend. Pero no las masivas. Eso si, si sรณlo hacemos esto con otro nombre no usa resize2 al subir productos. Tenemos que indicarle que lo haga. Para eso.
- Hacer un override en override/controllers/admin/AdminProductsController.phpย . Ahรญ hay 5 sitios en el que llama a resize. Cambia los 5 a la funciรณn anterior (pon un 2 y ya estรก si has usado nuestro mรฉtodo.
Para las importaciones masivas desde ficheros CSV o Excel en el backend.
Sรณlo modificando el ImageManager no arreglaba las importaciones masivas. Estas van “por otro lado”. Usaban en resize pero ademรกs el GD de nuevo. Para eso tenemos que hacer lo siguiente.
- Ahora copiamos el fichero controladorย AdminImportController.php en override/controllers/admin/AdminImportController.php
- Lo editamos y verรฉis que hay dos sitios que usan la biblioteca resize. Para el resultado que querรญamos el primero hay que dejarlo usando la original (con resize) y el segundo el resize2. Asรญ:
ImageManager::resize($tmpfile, $path.’.jpg’, null, null, ‘jpg’, false, $error, $tgt_width, $tgt_height, 5, $src_width, $src_height);
$images_types = ImageType::getImagesTypes($entity, true);if ($regenerate) {
$previous_path = null;
$path_infos = array();
$path_infos[] = array($tgt_width, $tgt_height, $path.’.jpg’);
foreach ($images_types as $image_type) {
$tmpfile = self::get_best_path($image_type[‘width’], $image_type[‘height’], $path_infos);if (ImageManager::resize2(
$tmpfile,
$path.’-‘.stripslashes($image_type[‘name’]).’.jpg’,
$image_type[‘width’],
$image_type[‘height’],
‘jpg’,
false,
$error,
$tgt_width,
$tgt_height,
5,
$src_width,
$src_height
Con esto nuestra imรกgenes han mejorado notablemente. Puedes modificar o aรฑadir los filtros usados (deberรญas) en ImageMagick. Esta pรกgina nos vino muy bien para entenderlos y hacer pruebas. Aquรญ las librerรญas de PHP.
Tambiรฉn os recomiendo que subรกis el tamaรฑo de las imรกgenes a uno de mucha resoluciรณn en las de producto. Luego podรฉis bajarlo por CSS. Pero la diferencia es notable si usรกis fotos de, digamos 1500px o de 900px.
Os recomendamos los siguientes productos relacionados con la informรกtica: