php - make - ¿Cómo cambio el tamaño y la conversión de una imagen cargada a un PNG usando GD?
laravel 5.6 intervention (9)
¿Es absolutamente necesario GD? ImageMagick es más rápido, genera mejores imágenes, es más configurable, y finalmente es (IMO) mucho más fácil de codificar.
Quiero permitir que los usuarios carguen imágenes de tipo avatar en una variedad de formatos (al menos GIF, JPEG y PNG ), pero que los guarden como BLOB de base de datos PNG . Si las imágenes están sobredimensionadas, en píxeles, quiero redimensionarlas antes de insertar DB.
¿Cuál es la mejor manera de usar GD para hacer el cambio de tamaño y la conversión PNG?
Editar: Tristemente, solo GD está disponible en el servidor que necesito usar, no ImageMagick .
¿Estás seguro de que no tienes ImageMagick en el servidor?
Yo huésped que usas PHP (la pregunta está etiquetada con PHP). La empresa de alojamiento que utilizo no tiene activada la extensión ImageMagick según phpinfo ().
Pero cuando les pregunté sobre lo que dijeron, aquí está la lista de programas de ImageMagick disponibles a partir del código PHP . Simplemente, no hay interfaz de mensajería instantánea en PHP, pero puedo llamar a los programas de mensajería instantánea directamente desde PHP.
Espero que tengas la misma opción.
Y estoy totalmente de acuerdo: almacenar imágenes en la base de datos no es una buena idea.
Algo como esto, tal vez:
<?php
//Input file
$file = "myImage.png";
$img = ImageCreateFromPNG($file);
//Dimensions
$width = imagesx($img);
$height = imagesy($img);
$max_width = 300;
$max_height = 300;
$percentage = 1;
//Image scaling calculations
if ( $width > $max_width ) {
$percentage = ($height / ($width / $max_width)) > $max_height ?
$height / $max_height :
$width / $max_width;
}
elseif ( $height > $max_height) {
$percentage = ($width / ($height / $max_height)) > $max_width ?
$width / $max_width :
$height / $max_height;
}
$new_width = $width / $percentage;
$new_height = $height / $percentage;
//scaled image
$out = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
//output image
imagepng($out);
?>
No he probado el código, por lo que podría haber algunos errores de sintaxis, sin embargo, debería darle una presentación justa sobre cómo se podría hacer. Además, asumí un archivo PNG. Es posible que desee tener algún tipo de instrucción de cambio para determinar el tipo de archivo.
Creo que esta página es un buen punto de partida. Utiliza imagecreatefrom (jpeg / gif / png), redimensiona y convierte la imagen y luego la envía al navegador. En lugar de dar salida al navegador, podría generar un BLOB en un DB sin muchos detalles de reescritura de código.
Si desea usar gdlib, use gdlib 2 o superior. Tiene una función llamada imagecopyresamplled (), que interpolará píxeles al redimensionar y se verá mucho mejor.
Además, siempre he escuchado que en toda la red, el almacenamiento de imágenes en la base de datos es de mala calidad:
- Es más lento acceder que el disco
- Su servidor necesitará ejecutar un script para llegar a la imagen en lugar de simplemente servir un archivo
- Su script ahora es responsable de muchas cosas que el servidor web solía manejar:
- Establecer el encabezado apropiado de tipo de contenido
- Establecer los encabezados adecuados de caché / tiempo de espera / etiqueta electrónica, para que los clientes puedan almacenar correctamente la imagen en caché. Si no lo haces correctamente, se aplicará el script de publicación de imágenes en cada solicitud, aumentando aún más la carga en el servidor.
La única ventaja que puedo ver es que no necesita mantener sincronizados sus archivos de imágenes y de base de datos. Aun así, lo recomendaría en contra.
Sus pasos de proceso deberían verse así:
- Verificar el tipo de archivo
- Cargue la imagen si es un tipo de archivo admitido en GD usando imagecreatefrom *
- Cambiar el tamaño usando imagecopyresize o imagecopyresampleado
- Guarde la imagen usando imagepng ($ handle, ''filename.png'', $ quality, $ filters)
ImageMagick es más rápido, genera mejores imágenes, es más configurable, y finalmente es (IMO) mucho más fácil de codificar.
@ceejayoz Solo espera por el nuevo GD - es OOP como MySQLi y en realidad no está mal :)
Este artículo parece que se ajustaría a lo que quieres. Tendrá que cambiar la función save imagejpeg () a imagepng () y hacer que guarde el archivo en una cadena en lugar de enviarlo a la página, pero aparte de eso debería ser fácil de copiar / pegar en su código existente.
<?php
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {
list($width_orig, $height_orig, $type) = getimagesize($srcFile);
// Get the aspect ratio
$ratio_orig = $width_orig / $height_orig;
$width = $maxSize;
$height = $maxSize;
// resize to height (orig is portrait)
if ($ratio_orig < 1) {
$width = $height * $ratio_orig;
}
// resize to width (orig is landscape)
else {
$height = $width / $ratio_orig;
}
// Temporarily increase the memory limit to allow for larger images
ini_set(''memory_limit'', ''32M'');
switch ($type)
{
case IMAGETYPE_GIF:
$image = imagecreatefromgif($srcFile);
break;
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($srcFile);
break;
case IMAGETYPE_PNG:
$image = imagecreatefrompng($srcFile);
break;
default:
throw new Exception(''Unrecognized image type '' . $type);
}
// create a new blank image
$newImage = imagecreatetruecolor($width, $height);
// Copy the old image to the new image
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output to a temp file
$destFile = tempnam();
imagepng($newImage, $destFile);
// Free memory
imagedestroy($newImage);
if ( is_file($destFile) ) {
$f = fopen($destFile, ''rb'');
$data = fread($f);
fclose($f);
// Remove the tempfile
unlink($destFile);
return $data;
}
throw new Exception(''Image conversion failed.'');
}
phpThumb es una abstracción de alto nivel que puede valer la pena mirar.