Cómo realizar el upload de una imagen y su manipulación en una aplicación Laravel, usando una librería llamada Intervention Image.
Intervention Image es una librería para el procesamiento de imágenes mediante el lenguaje PHP. La biblioteca resulta bastante avanzada y útil en muchas circunstancias.
En un pasado artículo ya tuvimos ocasión de hablar de ella de manera general, de modo que nos vamos a ahorrar las introducciones. Si quieres consultar más información puedes acceder al artículo de Intervention Image. En este caso vamos a realizar el ejemplo práctico para ver cómo se construiría una funcionalidad de upload de imágenes en una aplicación Laravel.
Instalación de Intervention Image
En una aplicación Laravel instalamos Intervention Image mediante el siguiente comando de Composer.
composer require intervention/image
Una vez instalado el paquete intervention/image
mediante Composer ya estamos en disposición de usar la librería.
En el momento de escribir este artículo Laravel todavía requiere Intervention Image 2.7 (o al menos mis dependencias así lo exigen) por lo que este artículo trata esta versión de la librería. Intervention Image actualmente está en la 3.x. Si necesitas código con esa versión consulta la documentación.
Formulario para la carga de una imagen
En una vista de la aplicación realizaremos el formulario para la carga de la imagen. Contiene un campo input
de tipo file
que es el que nos permitirá seleccionar la imagen del disco duro.
<form action="/upload-image" method="POST" enctype="multipart/form-data">
@csrf
<label for="image">Selecciona la imagen que deseas cargar:</label>
<input type="file" name="image" id="image">
<button type="submit">Cargar Imagen</button>
</form>
En este formulario encontramos algunos detalles importantes:
- El atributo
action="/upload-image"
indica la ruta de la aplicación donde vamos a enviar la imagen. - Muy importante el atributo
enctype="multipart/form-data"
, que es necesario para poder enviar archivos binarios a través del formulario.
Definición de una ruta para controlar este upload
La ruta de aplicación tiene que atender a solicitudes de tipo POST. Quedaría más o menos así:
Route::post('/upload-image', '[TuControlador]@uploadImage');
Controlador para guardar la imagen
Ahora vamos a ver el controlador que nos permite guardar la imagen en el disco del servidor. Veremos todo el código del controlador de una vez y luego lo comentamos.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManagerStatic as Image;
public function uploadImage(Request $request)
{
// Comenzamos validando la imagen, si lo consideras necesario, ajustando los valores a los que tú requieras.
$request->validate([
'image' => 'required|image|max:2048', // Valida que el archivo sea una imagen y no exceda los 2MB
]);
// Obtenemos la referencia al archivo cargado del Request.
$file = $request->file('image');
// Creamos un objeto Image a partir de Intervention Image
$image = Image::make($file);
// Modificar la imagen como lo necesites en tu caso
$image->widen(1600, function ($constraint) {
$constraint->upsize();
});
$image->heighten(1600, function ($constraint) {
$constraint->upsize();
});
// Generar un nombre único para la imagen
$this->path = uniqid() . '-' . $file->getClientOriginalName();
// Guardar la imagen en una ruta determinada
$image->save(storage_path('app/upload_images/' . $this->path));
// Respuesta, por ejemplo, un mensaje de éxito
return back()->with('success', 'Imagen cargada correctamente.');
}
El código está comentado para que lo puedas entender perfectamente. Obviamente, tendrás que modificarlo para que se ajuste a tus necesidades. La librería tiene muchas funcionalidades para la manipulación de las imágenes. Sería ideal que consultas esta documentación para obtener más información.
Algunos puntos destacables de este código son:
- Estamos usando los mecanismos de Intervention Image que funcionan con métodos estáticos, pero en la documentación puedes ver alternativas con métodos de objeto, si los prefieres.
- Los métodos
widen()
yheighten()
los usamos para cambiar el ancho y el alto de la imagen respectivamente, respetando las proporciones. - Usamos la función anónima que recibe
$constraint
para definir unas reglas a respetar al crear las nuevas dimensiones de la imagen. en este caso con el métodoupsize()
lo que conseguimos es prevenir que la imágen se redimensione a un tamaño mayor si no llega al tamaño objetivo. Es decir, si la imagen es mayor que las dimensiones nuevas la escalará haciéndola de un tamaño más reducido, pero si la imagen es menor no aumentará su tamaño. - La función
uniqid()
es nativa de PHP y nos permite obtener un identificador único basado en el timestamp actual. - El método
storage_path()
es un helper de Laravel que te entrega la ruta en el disco en el servidor para una ruta relativa que tú le pases.
Alternativa usando la fachada de Storage
En este ejemplo hemos almacenado el archivo en un disco del sistema de almacenamiento usando el método save()
del propio objeto Image de la biblioteca Intervention Image, pero podrías almacenar en otro disco utilizando la fachada Storage.
Para ello puedes tomar como referencia un código como este:
Storage::disk('tempImage')->put($filename, (string) $image->encode());
Cómo comprobar que la imagen tiene un tipo de archivo determinado
Por último y como extra vamos a ver el código para mejorar una regla de validación para Laravel. Ahora comprobaremos el tipo de la imagen enviada, para que sea de una extensión de archivo permitida.
Además vamos a validar también la dimensión de la imagen para que esté comprendida entre un tamaño máximo y un tamaño mínimo.
Para ello el array de validaciones podría ser algo como esto:
[
'image' => 'required|image|mimes:jpg,png,jpeg|max:6144|dimensions:min_width=64,min_height=64,max_width=5000,max_height=5000',
]
Conclusión
Hemos visto cómo usar la librería Intervention Image en Laravel para hacer un upload de un archivo de imagen, en el que hemos hecho un par de transformaciones sencillas. Espero que este ejemplo sea de utilidad y hayas comprobado lo fácil que es realizar el upload de ficheros de tipo imagen en el servidor usando el framework PHP Laravel.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...