Recentemente comecei a pesquisar diferentes temas que poderiam ser utilizados para escrever algum conteúdo, foi aí que um amigo escreveu o primeiro artigo e utilizou de um problema que aconteceu em seu dia a dia para transformá-lo em uma ideia de artigo, para escrever esse pequeno artigo resolvi tentar da mesma maneira.
Passamos por uns erros no quesito de upload de uma imagem para a api via Base64, resolvi então mostrar aqui alguns problemas dessa abordagem e uma alternativa para a mesma.
Base64 é um método para codificação de dados para transferência na Internet. É utilizado frequentemente para transmitir dados binários por meios de transmissão que lidam apenas com texto, como por exemplo para enviar arquivos anexos por e-mail.
Para converter um arquivo para Base64 no flutter é muito simples vide código baixo:
File file = await ImagePicker.pickImage(source: ImageSource.camera);
String base64 = base64Encode(file.readAsBytesSync());
¹ ImagePicker - Plugin Flutter para iOS e Android para selecionar imagens da galeria ou tirar uma nova foto com a câmera. Link
Obtido o Base64, o mesmo pode ser enviado no body de uma requisição post por exemplo.
Problemas com Base64
Respostas de API ficam muito grandes
Respostas muito grandes tendem a levar mais tempo para serem processadas dando mais tempo para uma possível falha na rede e aumentando o consumo de dados do dispositivo.
Oversizing
O tamanho da imagem codificada em Base64 é aproximadamente 30% maior do que a imagem binária original.
A experiência do usuário é afetada negativamente.
Incluindo os retornos junto com outras respostas da API, o aplicativo irá esperar carregar todos os dados antes de exibir informações na tela, afetando assim a experiência do usuário que verá uma tela de carregamento por mais tempo.
O armazenamento em cache de imagens no dispositivo não é mais possível.
Imagens enviadas para o dispositivo via Base64 tornará irrelevante qualquer implementação de serviços de cache de armazenamento de imagens.
Recursos nativos do flutter como o precacheImage tornam-se inutilizáveis nesta situação, já que toda vez será necessário fazer o decode do base64.
Outra implementação que se torna inutilizável seria o cachedNetworkImage, outra implementação nativa do flutter, mas que não pode ser aplicada ao contexto de um Base64.
Para aplicativos que possam funcionar tanto online quanto offline, a utilização de cache de imagens é um recurso bem eficaz para melhor experiência do usuário.
Vantagens do Base64
- Remover a necessidade de múltiplos request, para obtenção de dados. ²
- Imagens codificadas como Base64 podem ser armazenadas em bancos de dados e gerados novos arquivos. ² Como foi mostrado antes, essa abordagem pode ser uma vantagem ou uma desvantagem a depender do contexto e da implementação
Multipart Form Data
- É uma de três formas de codificação existentes no HTML sendo elas:
1.application/x-www-form-urlencoded
2.multipart/form-data
3.text/plain
- Deve-se utilizar esta forma de codificação quando a requisição possuir algum arquivo que deve fazer upload
- É compatível com todos os navegadores.
- Suporta arquivos com tamanhos muito grandes.
Utilizando multipart com Flutter
File file = await ImagePicker.pickImage(source: ImageSource.camera);
final multiPartdata = await MultipartFile.fromFile(file.path);
final formData = FormData.fromMap({
"file": multiPartdata,
});
Desta maneira o servidor da API deve estar preparado para receber requisições com o cabeçalho multipart/form-data, já que o conteúdo não irá junto com o body da requisição caso o mesmo exista.
Alguns servidores de storage como aws.s3, cloudinary, firebase cloud storage, estão preparados para receberem requisições nesse formato, possuindo libs para integração direta em Flutter, dispensando a necessidade da criação de uma api própria.
Resolvendo o Oversizing
Algumas estratégias podem ser admitidas a fim de reduzir o oversizing, a mais comum são os famosos thumbnails, algumas alternativas mais recentes que têm grande aplicabilidade a depender do contexto seriam o blurHash e a Dominant color abaixo explico o funcionamento de ambas.
Thumbnails
Uma thumbnail é uma imagem comprimida que prevê a imagem original. Elas são mais leves e podem ser utilizadas para diversos fins. Por exemplo, um dos propósitos da utilização dessa thumb é reduzir o tempo de carregamento de alguma pagina na internet, para tornar o acesso mais rápido ao usuário. Então, uma thumbnail de uma foto maior, seria uma versão reduzida dela mesma.
Em essência, a principal função de uma miniatura é trazer uma informação ao usuário de maneira mais rápida.
Blurhash
“BlurHash is a compact representation of a placeholder for an image”.
Blurhash é uma representação compacta de um espaço reservado para uma imagem. Esta é a definição dada pelos desenvolvedores. Trata-se de uma biblioteca que converte uma imagem para uma versão ofuscada e compactada de sua versão.
Essa biblioteca possui implementações para diversas linguagens, typescript, kotlin, swift, python, C, entre outras. Segue abaixo uma visão da mesma.
Dominant color
Trata-se apenas de pegar a cor de maior incidência na imagem, e utilizá-la no local da mesma. Estratégia bastante parecida com o blurHash, a diferença seria apenas o resultado final da imagem.
Referencial Bibliográfico
https://medium.com/snapp-mobile/dont-use-base64-encoded-images-on-mobile-13ddeac89d7c
https://pt.wikipedia.org/wiki/Base64
https://pub.dev/packages/image_picker
https://medium.com/snapp-mobile/dont-use-base64-encoded-images-on-mobile-13ddeac89d7c
http://www.coderiddles.com/base64-images/
https://neilpatel.com/br/blog/thumbnail-o-que-e/
https://github.com/woltapp/blurhash
Top comments (0)