Otimizando imagens com Cloudinary e Django Api RESTful

Olá, bem vindos a minha primeira postagem. Estou fazendo uma Api Restful com Python/Django e hospedei a mesma no Heroku, neste projeto será necessário servir algumas imagens, entretanto o Heroku não é capaz de me atender neste quesito, pois não armazena os arquivos além da sua aplicação, então para que possamos servir imagens e arquivos para nossos usuários será necessário algum serviço externo, como o da Amazon ou Cloudinary, optei por utilizar o Cloudinary.

O Cloudinary é um serviço de armazenamento de imagens e vídeos que ainda lhe fornece diversas ferramentas para otimização das imagens deixando seus arquivos leves como pena. Com a versão Free é possível utilizar 10 GBs de armazenamento

3 bons motivos para otimizar suas imagens segundo Prosper Otemuyiwa
SEO: a velocidade do seu site é uma importante classificação e fator de engajamento. Se suas imagens estiverem otimizadas, seu site será mais rápido. O tempo de carregamento e o tamanho geral do seu site têm um impacto direto nas classificações do seu mecanismo de pesquisa.
Armazenamento: otimizar suas imagens resulta em tamanhos reduzidos de arquivos de imagem, o que, por sua vez, reduz a quantidade de espaço de armazenamento necessário para alojar suas imagens.
Largura de banda: otimizar suas imagens economizará muita largura de banda. O uso reduzido de largura de banda reduz os custos do seu plano de hospedagem e salvará automaticamente seus usuários de algum montante nos custos dos dados usados para navegar no seu site.

Parecem ótimos motivos não? Iremos utilizar o Django Rest Framework, caso não saiba como utilizar, veja este vídeo da [PK] Paola Katherine, ela explica muito bem como funciona.

Let’s get started

Assumindo que você já criou seu projeto Django e se cadastrou no cloudinary, você tem as seguintes informações em seu painel.

Utilizaremos os dados destacados em amarelo.

pip install cloudinary
pip install Pillow

Instale a biblioteca python com o pip.

Em seu arquivo Settings.py adicione esse código.

myproject/
|-- myproject/
|    |-- myapp/
|    |-- myproject/
|    |    |-- settings.py  <-- aqui!
|    |    |-- urls.py   
|    |    |-- wsgi.py
|    +-- manage.py

Em seu aplicativo, no arquivo models.py. Use este código.

Após adicionar o model é necessário rodar o comando makemigrations

python manage.py makemigrations

Assim o Django irá mapear a tabela, após isso podemos criar nossa tabela utilizando o comando migrate

python manage.py migrate

No mesmo diretório do models.py, crie um arquivo serializer.py.

myproject/
|-- myproject/
|    |-- myproject/
|    |-- myapp/
|    |    |-- admin.py
|    |    |-- models.py
|    |    |-- tests.py
|    |    |-- views.py
|    |    +-- serializer.py <-- aqui!
|    +-- manage.py

serializer.py

Vamos criar nossa View para exibir os dados. No arquivo views.py, adicione o seguinte código.

Localize o arquivo urls.py e adicione a view ImagemCloud

Para rodar nosso aplicativo , vá no terminal e use o comando

python manage.py runserver

Podemos acessar com o link:

http://127.0.0.1:8000/imagens/

Se você estiver vendo essa tela, por hora está tudo funcionando.

Adicione o método POST abaixo do GET.

Pronto, nossa aplicação já está preparada para receber nossa primeira imagem.

Postman

Para facilitar a utilização iremos usar Postman. Após abrir o Postman adicione a Url e remova o Header, como na imagem.

Em Body , Adicione o nome da Key(atributo do seu model) e mude o tipo de Text para File e procure uma imagem em seu computador. Utilizarei o archer.jpg, apos isso click em “Send”

Se tudo deu certo e nada deu errado, basta atualizar o Cloudinary e procurar seu arquivo.

Atualize sua pagina Django e você verá algo como isso.

Como pode ver, não recebemos um link para as imagens. ‘‘Mas Thallison, eu quero o Link’’

Calma jovem, vamos entender a string que recebemos. Ao enviar a imagem para o Cloudinary, ele tratou de gerar um diretório para armazenar as imagens, então ‘image’ e ‘upload’ representam a pasta em que o nosso arquivo está armazenado, também temos uma sequência de número “v1508956329”, este número representa a versão da sua imagem, você pode armazenar mais de uma versão para uma mesma imagem, para saber mais clique Aqui. E por último temos “rsx9elkvtxpm847ps3fg.jpg” que é o nome do nosso arquivo e o formato da imagem, internamente o Cloudinary referência esse nome como public_id.

Para recebemos o link completo é necessário uma adição no arquivo serializer.py.

Atualizando a pagina novamente temos o link completo.

Clicando no link somos redirecionados para a imagem que enviamos anteriormente.

Como o foco aqui não é usar essa imagem em Forms ou Templates, não irei abordar esse assunto, mas caso tenha interesse, pode usar este link.

A imagem que carregamos não passou por nenhum tratamento, ela está com seu tamanho original, então vamos conferir algumas das possibilidades que o Cloudinary nos oferece, utilizarei uma segunda imagem, uma foto de uma lasanha que eu fiz, como a imagem possui efeitos está com um tamanho maior que o normal.

Atualmente seu tamanho é de 1,94 MB, vamos enviar usando código python e passando alguns parâmetros para ver o que acontece. Altere o arquivo views.py com o seguinte código.

Observe que o método save() foi comentado, pois não faremos mais upload pela forma mostrada anteriormente.

Antes de enviar vamos analisar alguns parâmetros.

Primeiro pegamos a imagem do request, note que o nome do arquivo é o mesmo do models.py.

public_id representa o nome da sua imagem no Cloudinary.

Tags é opcional, você pode passar algumas para organizar suas imagens por categorias.

Todos os parâmetros utilizados foram de um sample da documentação, alterei apenas os items mencionados acima.

Para enviar basta fazer o mesmo processo anterior no Postman. Vejamos se houve alguma alteração na imagem.

A imagem agora possui 376.6KB, um Nome e duas tags.

Deixei as imagens lado a lado para que você possa comparar e tirar suas conclusões. Esquerda Original, Direita Alterada.

Observação: Fiz diversos testes e não conseguir obter as imagens que não possui um public_id, se você souber como, compartilhe conosco sua solução, com isso em mente, o código a seguir é valido apenas se enviou suas imagens da segunda maneira, entretanto também é possível redimensionar as imagens direto no Template Django

Utilizarei as imagens em um App Android, então vamos redimensionar a imagem para que possamos ter um tamanho ainda mais reduzido.

Adicione esse código no serializer.py dentro do to_representation, adicione também um breakpoint para analisar o conteúdo da variável imagemURL, rode o server novamente.

python manage.py runserver

Observe que busco a imagem passando o nome, o seu public_id, ele me retorna a Url da imagem.

Este link me trouxe a imagem desse jeito.

Deixei a tela inteira para que você tenha noção da proporção da imagem, apesar de parecer pequena, e realmente é, mas no Android funciona muito bem, neste momento essa imagem está com apenas 4.51KB

Com o atributo quality, posso trazer essa imagem em diferentes qualidades. Como: auto:best, auto:good, auto:eco, auto:low, e 80(esse numero pode ser alterado entre 0 e 100, proporcionando um maior controle das imagens)

Com o parâmetro good, a imagem ficou ainda menor sem perdas de qualidade aparente.

Na hipótese da imagem ser de perfil, utilize este código, o algoritmo irá procurar um rosto na foto para cortar e então ajustar da melhor maneira.

Caso você queria utilizar apenas a segunda solução, você pode mudar seu models.py e transforma-lo em CharField ou adicionar um campo CharField para armazenar o nome da imagem, desde que tenha optado por fazer alguma dessas alterações, deixe seu serializer.py próximo disso.

Por hoje é isso, se encontrou algum erro ou incoerência, não seja tímido, comente que atualizarei assim que possível.