Subir y recortar imagenes con Expressjs
Tags: node, javascript, express, newbie
Published: 2021-02-12 00:52:26

Hola, algo bastante complicado(no debería serlo) es encontrar la forma de subir imágenes, recortarlas y mostrarlas en Expressjs.

Lo primero que tenemos que hacer es requerir las siguientes dependencias:

- serve-static (Para servir archivos estáticos)
- multer (Para subir las imágenes)
- jimp (Para recortar las imágenes)

```javascript
const multer = require('multer');
var Jimp = require('jimp');

const storage = multer.diskStorage({

    destination: (req, res, callback) => {
        callback(null, './public/files');
    },
    filename: async (req, file, callback) => {
        let image = file.originalname;
        callback(null, Date.now()+ '_' +image.replace(/ /g, ""));
    }
})
const upload = multer({storage}); 
```
Lo primero es guardar la configuración de multer en una variable; lo que hacemos es llamar al método diskStorage que recibe un objeto con dos valores:

**destination:** Como dice el nombre del valor, es para definir donde se van a guardar las imágenes, este devuelve una funcion que tiene 3 parámetros, req, res y callback, y a callback le pasamos como segundo parámetro el path donde vamos a guardar la imagen.

**filename:** Es la opción para especificar con que nombre vamos a guardar las imágenes, en este caso tambien debemos pasarle una función y esa función recibe los mismos parámetros que destination, lo que yo hice fue tomar el nombre original de la imágen y guardarlo en una variable, luego de esto le puse de nombre la fecha actual exacta y lo concatené con el nombre original de la imagen pero sacándole todos los espacios.

Luego de esto guardamos toda esta configuración adentro de una variable en donde le pasamos un objeto con la variable storage adentro. Esto nos va a servir para poder usarla como middleware.


```javascript
router.post('/image/upload', upload.single('formData'), async (req, res) => {
    console.log(req.file)
    const filepath = Date.now()+req.file.filename.replace(/ /g, "")
    const image = await Jimp.read(req.file.path)
    image.resize(600, 500) 
    .quality(90)
    .writeAsync(`./public/image_resize/${filepath}`)
    res.json({
        data: `![](http://localhost:3000/image_resize/${filepath})`
    })
})
```

Ahora en la ruta donde queremos usar para subir la imágen vamos a pasarle como middleware la variable upload, donde le especificamos con el método single que queremos cargar un solo archivo que vamos a recibir a través de formData.

Leemos la imagen a través de jimp con el método read y lo guardamos en una variable.

A través de esa variable con el metodo resize recortamos la imagen al tamaño que nosotros queramos, con quality le decimos con que calidad queremos guardar la imagen y con write o writeAsync le especificamos en qué lugar guardamos la imagen recortada.

Luego de esto le enviamos al usuario el path desde donde vamos a mostrar la imagen.


Ahora se viene la parte de poder mostrar las imagenes guardadas.

Para esto vamos a utilizar serve-static, en app.js le especificamos la ruta que queremos servir a traves de http para que las imagenes que guardamos puedan ser vistas a través del navegador:

```javascript
app.use(serveStatic(path.join(__dirname, '/image_resize/')));
```
Ahora, si entramos a la url que nos devuelve mi api:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/675y34ajvp16qcjzyja7.png)

vamos a ver la imagen recortada
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3hq10kiw17z33uukzx3j.png)

En el próximo post les voy a mostrar como validar que los archivos que se suben sean imágenes.