Contents

Comprimindo imagens em Node.js com Sharp

Imagens desnecessariamente grandes podem levar a tempos de resposta mais lentos, consumir largura de banda excessiva e proporcionar uma experiência lenta aos utilizadores, especialmente aos que têm ligações mais lentas. Isto pode resultar em taxas de rejeição mais elevadas ou menos conversões.

Antes de transmitir ficheiros multimédia digitais, a compressão dos seus componentes visuais pode ajudar a aliviar potenciais complicações e fornecer uma interface de utilizador melhorada. Neste sentido, o módulo Sharp apresenta uma solução simples e expedita para atingir este objetivo.

Configurar o seu ambiente de desenvolvimento

Para ilustrar o procedimento de redução do tamanho do conteúdo visual, comece por implementar uma funcionalidade de carregamento de ficheiros utilizando o Multer. É possível acelerar o processo duplicando o código deste repositório do GitHub.

Para configurar com êxito o serviço de upload de imagens a partir de um repositório GitHub clonado, execute o seguinte comando para instalar as dependências necessárias:

 npm install

Em seguida, instale o Sharp executando este comando:

 npm install sharp

O módulo Sharp é uma biblioteca Node.js de alto desempenho para processamento e manipulação de imagens. Você pode usar o Sharp para redimensionar, cortar, girar e executar várias outras operações em imagens de forma eficiente. O Sharp também tem um excelente suporte para comprimir imagens.

Técnicas de compressão para diferentes formatos de imagem

Diferentes formatos de imagem empregam estratégias de compressão exclusivas, uma vez que são adaptadas para atender a casos de uso específicos e considerações como qualidade, dimensões do arquivo e atributos como transparência e recursos de animação.

JPG/JPEG

O JPEG, ou o padrão de compressão de imagem do Joint Photographic Experts Group, foi especificamente concebido para comprimir fotografias e outras imagens que apresentam gradações contínuas de tons e cores. Utilizando uma forma única de compressão com perdas, reduz eficazmente o tamanho do ficheiro, descartando seletivamente determinados aspectos dos dados da imagem original.

Em primeiro lugar, importe o módulo Sharp; em segundo lugar, forneça o caminho para o ficheiro de imagem ou uma memória intermédia que contenha o seu conteúdo; em terceiro lugar, utilize o método .jpeg da instância Sharp importada; por último, inclua um objeto de configuração com um atributo quality definido para um valor numérico que varia entre 0 e 100, em que os valores mais baixos representam ficheiros mais pequenos mas com uma qualidade visual inferior, enquanto os valores mais altos produzem ficheiros maiores com melhor nitidez.

O utilizador pode ajustar o parâmetro de acordo com os seus requisitos específicos.Para obter um desempenho de compressão ótimo, recomenda-se que o valor seja mantido entre 50 e 80, de modo a obter um equilíbrio adequado entre o tamanho do ficheiro e a fidelidade da imagem.

Conclua armazenando a representação comprimida no sistema de ficheiros utilizando o método .toFile , passando o caminho do ficheiro de saída pretendido como parâmetro.

Por exemplo:

 await sharp(req.file.path)
        .jpeg({ quality: 60 })
        .toFile(`./images/compressed-${req.file.filename}`)
        .then(() => {
          console.log(`Compressed ${req.file.filename} successfully`);
        });

A configuração padrão para a qualidade da imagem é definida em 80 por padrão.

PNG

PNG, ou Portable Network Graphics, é um formato de ficheiro de imagem amplamente reconhecido que é conhecido pela sua capacidade de fornecer compressão de dados sem perdas, ao mesmo tempo que suporta transparência nas imagens, tornando-o altamente versátil e ideal para várias aplicações.

Ao tentar compactar uma imagem salva no formato PNG (Portable Network Graphics) usando o Sharp, é importante observar que o processo compartilha várias semelhanças com a compactação de uma imagem comparável salva como um arquivo JPEG (Joint Photographic Experts Group). No entanto, existem dois ajustes distintos que devem ser efectuados durante este procedimento.

A utilização do formato de ficheiro PNG, em oposição ao JPEG, é a forma como a Sharp lida com o processamento de imagens.

O formato PNG emprega uma nova abordagem à compressão, utilizando o parâmetro “compressionLevel”, em vez da tradicional definição de “qualidade”, como forma de controlar o nível de compressão alcançado. Na sua definição mais baixa (0), o algoritmo produz a redução mais rápida e mais extensa no tamanho do ficheiro, enquanto na sua definição mais alta (9), produz a compressão mais lenta e menos substancial.

Por exemplo:

 await sharp(req.file.path)
        .png({
          compressionLevel: 5,
        })
        .toFile(`./images/compressed-${req.file.filename}`)
        .then(() => {
          console.log(`Compressed ${req.file.filename} successfully`);
        });

Por padrão, o valor atribuído ao nível de compactação é definido como 6.

Outros formatos

O Sharps também oferece suporte à compactação de imagens em uma variedade de formatos de arquivo adicionais, incluindo:

A utilização do algoritmo de compressão de imagem WebP em conjunto com o Sharp segue um procedimento semelhante ao da utilização de JPEG, com a única distinção a ser o requisito de invocar o método webp da instância Sharp em vez do método .jpeg .

O Tagged Image File Format (TIFF) utilizado para comprimir imagens na implementação do Sharp segue um procedimento semelhante ao utilizado pelo JPEG, embora com uma invocação de método alternativa. Em vez de chamar o método “.jpeg” na instância Sharp, é necessário invocar o método “tiff”.

O formato AVID, que pertence ao formato de ficheiro de imagem AV1 utilizado na compressão de imagens pela Sharp, funciona de forma semelhante ao JPEG.No entanto, em vez de utilizar o método .jpeg numa instância Sharp, é necessário utilizar o método avif. Além disso, vale a pena referir que o valor predefinido para a definição de qualidade no formato AVIF está definido para 50.

O HEIF, que significa High Efficiency Image File Format (Formato de ficheiro de imagem de alta eficiência), utiliza um procedimento semelhante em termos de compressão quando comparado com o JPEG. No entanto, requer a utilização do método heif em vez do método .jpeg na instância Sharp. Além disso, por defeito, o AVIF tem uma definição de qualidade de imagem de 50.

Compressão de imagens com o Sharp

Se tiver reproduzido o repositório GitHub, é necessário aceder ao ficheiro “app.js” no projeto e incorporar as declarações de importação mencionadas anteriormente.

 const sharp = require("sharp");
const { exec } = require("child_process");

A função exec , disponibilizada pelo módulo child_process , permite a execução de comandos shell ou de processos externos numa aplicação Node.js.

Esta função permite-lhe executar um comando que compara as dimensões de um ficheiro antes e depois da sua compressão.

Em seguida, vamos substituir o atual manipulador POST '/single' incorporando nele o trecho de código fornecido.

 app.post("/upload-and-compress", upload.single("image"), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(404).send("Please upload a valid image");
    }

    const compressedFileName = req.file.filename.split(".")[0];
    const compressedImageFilePath = `./images/${compressedFileName}-compressed.png`;

    await sharp(req.file.path)
      .jpeg({ quality: 50 })
      .toFile(compressedImageFilePath)
      .then(() => {
        let sizeBeforeCompression, sizeAfterCompression;
        const sizeBeforeCompressionCommand = `du -h ${req.file.path}`;
        const sizeAfterCompressionCommand = `du -h ${compressedImageFilePath}`;

        exec(sizeBeforeCompressionCommand, (err, stdout, stderr) => {
          sizeBeforeCompression = stdout.split("\\t")[0];

          exec(sizeAfterCompressionCommand, (err, stdout, stderr) => {
            sizeAfterCompression = stdout.split("\\t")[0];

            res.send({
              message: "Image uploaded and compressed successfully",
              sizeBeforeCompression,
              sizeAfterCompression,
            });
          });
        });
      });
  } catch (error) {
    console.log(error);
  }
});

A implementação de código acima mencionada engloba uma metodologia para comprimir ficheiros de imagem JPEG, ao mesmo tempo que realiza uma comparação dos respectivos tamanhos de ficheiro antes e depois de utilizar o comando du .

O comando du é um utilitário Unix que fornece informações sobre a utilização do disco, estimando a quantidade de espaço ocupado por ficheiros e directórios dentro de directórios especificados. Utilizando a flag -h , a saída pode ser apresentada num formato facilmente compreensível para humanos, indicando o espaço de ficheiro utilizado por subdirectórios individuais e os seus respectivos conteúdos.

Para iniciar a operação do seu serviço de transferência de arquivos, execute a seguinte instrução:

 node app.js

Para validar a funcionalidade do seu aplicativo, você pode utilizar o aplicativo cliente Postman ou qualquer ferramenta alternativa de teste de API de sua escolha para enviar uma imagem JPEG para o ponto de extremidade especificado " /upload-and-compress>" para processamento e compactação adicionais.

Espera-se que receba uma resposta que se assemelhe ao seguinte formato:

 {
  "message": "Image uploaded and compressed successfully",
  "sizeBeforeCompression": "13M",
  "sizeAfterCompression": "3.1M"
}

Outras utilizações do módulo Sharp

O módulo Sharp oferece uma gama abrangente de capacidades de manipulação de imagens para além da mera compressão. Estas incluem redimensionar, cortar, rodar e inverter imagens de acordo com as dimensões especificadas. Além disso, permite modificações no espaço de cor, operação de canal alfa e conversão entre diferentes formatos de ficheiro.