VAGAS DE EMPREGO

balta.io balta.io
  • Cursos
  • Carreiras
  • Para sua Empresa
  • Livros
    • Background Services
    • Blazor com .NET 8
    • Segurança em APIs
    • Futuro do C# 12
    • Nullable Types
    • Clean Code
  • Blog

Seja Premium
balta.io

  • Cursos
  • Carreiras
  • Para sua Empresa
  • Agenda
  • Livros
    • Background Services
    • Blazor com .NET 8
    • Segurança em APIs
    • Futuro do C# 12
    • Nullable Types
    • Clean Code
  • Blog
  • Player
Seja Premium

Entre ou Cadastre-se

  • Home
  • Artigos
  • Upload de imagem para o Azure Storage com C#


👉 Temos uma versão mais atualizada deste artigo no nosso novo Blog

Upload de imagem para o Azure Storage com C#

Em boa parte das aplicações que desenvolvemos, temos o envio de imagens. Hoje com as facilidades que temos no Frontend, é muito simples tratar uma imagem, recortar, aplicar efeitos e depois enviar para o servidor.

O que antes tinha de ser feito todo no Backend, hoje é dividido entre ambos. Porém, ainda temos o trabalho de capturar e armazenar esta imagem, mas onde?

No banco de dados não!

Quando comecei o balta.io (na época era ABT – André Baltieri Treinamentos), eu optei pelo mínimo de infraestrutura possível, e hospedava o site, API, app, tudo em um lugar só, na mesma máquina, sem escalonamento nem nada.

Nesta época, eu salvava as imagens em um banco de dados, afinal elas vinham como String da tela (Base64), então era simples.

O problema é que o banco cresce demais em tamanho, as imagens não podem ser reaproveitadas (Não temos uma URL), e sempre que precisamos de uma imagem, tem que ir até o banco.

Fora que sua thread não finaliza enquanto você não envia todas as informações para a tela, e neste caso, se você tem imagens grandes, você segura a thread da sua API e a conexão com o banco abertas enquanto o tráfego acontece.

Acabou que existem maneiras MUITO melhores de se armazenar imagens, como vou mostrar aqui.

Na mesma máquina não!

Bom, se não é legal colocar no banco de dados, então vamos salvar em disco, correto? Bem... quase...

Sempre que você salva uma imagem em disco, você está consumindo I/O desta máquina, em adicional, as requisições para esta imagem vão consumir recursos que podem ser vitais para sua API.

Como se tudo isto não bastasse, salvar local (Na mesma máquina) não escala!

Um dos modelos de escalonamento que mais usamos hoje é o horizontal, onde temos máquinas menores e várias delas.

Neste cenário, se nada estiver em uso, pagamos apenas por uma máquina pequena, que está ali em stand-by. Diferente de termos uma máquina mais poderosa, que custa mais caro.

Sendo assim, máquinas são criadas e destruídas a todo tempo, e quando elas são criadas, elas se baseiam em uma imagem, e advinha só... esta imagem contém apenas o SO.

Então é feito um novo build/deploy do seu App e a máquina é disponibilizada, o que significa que nada que estava na memória ou disco da(s) máquina(s) anterior(es) foi copiado junto.

Logo, se você salvou alguma imagem em uma máquina, ela ficou lá, apenas lá, e será destruída junto com a máquina assim que ela não estiver mais em uso.

Por que utilizar um Storage?

Se não recomendamos salvar no banco, e salvar em disco não escala, então para onde podemos correr? Para um Storage... no nosso caso o Azure Storage.

Como o nome já diz os Storages foram feitos para isto, eles armazenam arquivos e disponibilizam com backup, geolocalização, CDN e muito mais.

Os Storages ficam na mesma rede (Grupo de Afinidade) dos nossos Apps, porém rodam independentes, o que significa que não afetam o I/O ou processamento dos mesmos e estão sempre disponíveis... pode cair máquina, pode subir máquina, o Storage permanece lá.

Os Storages tem segurança, você pode obrigar a passagem de um Token para poder acessar um arquivo e todo arquivo tem uma URL, o que o torna rastreável e reutilizável.

Para finalizar os Storages são um dos recursos mais baratos que temos no Azure hoje.

Envio em Base64

Os Storages suportam envio de arquivos em Array de Bytes, porém, é comum no Frontend trabalharmos com Base64 quando falamos de imagens.

Existem várias bibliotecas para tratamento de imagem, desde recorte até efeitos, e a maioria delas tem como resultado a imagem como Base64.

Se você já tiver o Array de Bytes fica até mais fácil, pulamos um processo no código, mas na maioria das vezes você terminará com uma String.

Em termos de performance, Strings são mais pesadas que Arrays de Bytes para transferência, então se o seu foco é performance, talvez seja legal converter para binário antes de enviar para a API.

Criando o método de Upload

Eu particularmente crio um serviço de Upload de imagem, abstraindo o Azure da minha API, isto é importante para futuras mudanças na API.

Como o envio de imagem está estritamente ligado a infraestrutura, e ela pode mudar, recomendo que faça o mesmo, criando um método separado, em um serviço, na camada de infraestrutura da sua API.

Este método vai fazer o envio da imagem e retornar a URL dela.

public string UploadBase64Image(string base64Image, string container) { }

Pensando em melhorias, poderíamos até criar uma interface para este serviço, mas não vou cobrir isto aqui.

Gerando o nome do arquivo

Ao tentar enviar uma imagem já existente par ao Storage, você pode se deparar com um erro, ou forçar a sobrescrita da mesma.

Eu particularmente gosto de gerar nomes randômicos para evitar este tipo de problema. Em adicional, o Storage do Azure tem um ótimo cache, o que significa que se você sobrescrever uma imagem, ele possivelmente vai levar algumas horas para refletir esta mudança.

public string UploadBase64Image(string base64Image, string container) { 
    // Gera um nome randomico para imagem
    var fileName = Guid.NewGuid().ToString() + ".jpg";
}

Neste caso eu já aproveito também para definir o formato da imagem, que neste caso sempre será JPG, porém você pode extrair esta informação do Base64 que receberá, caso queira salvar no formato correto.

Preparando a imagem

Sempre que uma imagem no formato Base64 é enviada, ela contém primeiramente o formato da imagem, seguido pelo formato do Hash, neste caso, Base64.

Porém, para persistir estas informações isto não é necessário, e gera um erro. Temos então que remover esta parte.

Para isto, utilizei um Regex que faz a limpeza destas informações e já deixa tudo pronto para ser enviado.

public string UploadBase64Image(string base64Image, string container) { 
    // Gera um nome randomico para imagem
    var fileName = Guid.NewGuid().ToString() + ".jpg";
    
    // Limpa o hash enviado
    var data = new Regex(@"^data:image\/[a-z]+;base64,").Replace(base64Image, ""); 
}

Gerando o Array de Bytes

Conforme comentei previamente, para realizar o envio do arquivo, precisamos de um Array de Bytes, e isto pode ser feito utilizando o método Convert.FromBase64String do próprio C#.

public string UploadBase64Image(string base64Image, string container) { 
    // Gera um nome randomico para imagem
    var fileName = Guid.NewGuid().ToString() + ".jpg";
    
    // Limpa o hash enviado
    var data = new Regex(@"^data:image\/[a-z]+;base64,").Replace(base64Image, ""); 
    
    // Gera um array de Bytes
    byte[] imageBytes = Convert.FromBase64String(data);
}

Enviando a imagem

O primeiro passo é definir para onde vai a imagem. No Azure Storage temos os BLOBs e Containers, que definem o arquivo e “pasta” respectivamente.

Neste caso, estamos recebendo o Container por parâmetro e é importante frisar que este deve existir, caso contrário será retornado um erro.

Com tudo definido, podemos utilizar um MemoryStream para ler o Array de Bytes e fazer o upload deles para o Azure.

public string UploadBase64Image(string base64Image, string container) { 
    // Gera um nome randomico para imagem
    var fileName = Guid.NewGuid().ToString() + ".jpg";
    
    // Limpa o hash enviado
    var data = new Regex(@"^data:image\/[a-z]+;base64,").Replace(base64Image, ""); 
    
    // Gera um array de Bytes
    byte[] imageBytes = Convert.FromBase64String(data);
    
    // Define o BLOB no qual a imagem será armazenada
    var blobClient = new BlobClient("SUA CONN STRING", container, fileName);

    // Envia a imagem
    using(var stream = new MemoryStream(imageBytes)) {
        blobClient.Upload(stream);
    }
}

Obtendo a URL da imagem enviada

Por fim, tudo que precisamos fazer é retornar a URL da imagem que acabamos de enviar.

public string UploadBase64Image(string base64Image, string container) { 
    // Gera um nome randomico para imagem
    var fileName = Guid.NewGuid().ToString() + ".jpg";
    
    // Limpa o hash enviado
    var data = new Regex(@"^data:image\/[a-z]+;base64,").Replace(base64Image, ""); 
    
    // Gera um array de Bytes
    byte[] imageBytes = Convert.FromBase64String(data);
    
    // Define o BLOB no qual a imagem será armazenada
    var blobClient = new BlobClient("SUA CONN STRING", container, fileName);

    // Envia a imagem
    using(var stream = new MemoryStream(imageBytes)) {
        blobClient.Upload(stream);
    }
    
    // Retorna a URL da imagem
    return blobClient.Uri.AbsoluteUri;
}

Pronto, temos upload de imagem para o Azure com C# em 20 linhas de código.

Populares

Priority Queue

Priority Queue ou fila prioritária é um tipo de lista inclusa no C# 10 que permite que seus itens...


Implicit Operators no C#

Implicit Operators permitem adicionar comportamentos de conversão a objetos Built In ou complexos...


ASP.NET 5 – Autenticação e Autorização com Bearer e JWT

Este artigo atualmente utiliza a versão 5.0.0-rc.1 do ASP.NET/.NET, o que significa que ainda não...


Clean Code - Guia e Exemplos

Saiba como manter seu código limpo (Clean Code) seguindo algumas práticas sugeridas pelo Robert C...


Git e GitHub - Instalação, Configuração e Primeiros Passos

Git é um sistema de controle de versões distribuídas, enquanto GitHub é uma plataforma que tem o ...


Compartilhe este artigo



Conheça o autor

André Baltieri

André Baltieri

Microsoft MVP

Me dedico ao desenvolvimento de software desde 2003, sendo minha maior especialidade o Desenvolvimento Web. Durante esta jornada pude trabalhar presencialmente aqui no Brasil e Estados Unidos, atender remotamente times da ?ndia, Inglaterra e Holanda, receber 8x Microsoft MVP e realizar diversas consultorias em empresas e projetos de todos os tamanhos.





3.133

Aulas disponíveis

292

horas de conteúdo

76.438

Alunos matriculados

52.993

Certificados emitidos





Comece de graça agora mesmo!

Temos mais de 21 cursos totalmente de graça e todos com certificado de conclusão.

Começar


Prefere algo mais Premium?

Conheça nossos planos



Premium anual

Compra única, parcelada em até
12x no cartão de crédito


12x R$

99

,79

=R$ 1.197,44
  • 1 ano de acesso
  • Acesso à todo conteúdo
  • Emissão de Certificado
  • Tira Dúvidas Online
  • 67 cursos disponíveis
  • 10 carreiras disponíveis
  • 161 temas de tecnologia
  • Conteúdo novo todo mês
  • Encontros Premium

Começar agora

Política de privacidade



Precisa de ajuda?

Dúvidas frequentes



  • Posso começar de graça?

    Sim! Basta criar sua conta gratuita no balta.io e começar seus estudos. Nós contamos com diversos cursos TOTALMENTE gratuitos e com certificado de conclusão.

  • Vou ter que pagar algo?

    Nós temos cursos gratuitos e pagos, porém você não precisa informar nenhum dado de pagamento para começar seus estudos gratuitamente conosco. Os cursos gratuitos são completos e com certificado de conclusão, você não paga nada por eles.

    Porém, caso queira algo mais Premium , você terá acesso à diversos benefícios que vão te ajudar ainda mais em sua carreira.

  • Por onde devo começar?

    Siga SEMPRE as nossas Carreiras , elas vão te orientar em todos os sentidos. Os cursos já estão organizados em categorias e carreiras para facilitar seu aprendizado.
    Nossa sugestão para aprendizado é começar pelo Backend e seguindo para Frontend e Mobile.

    • Backend
    • Frontend
    • Mobile

  • Os cursos ensinam tudo que preciso?

    Nenhum curso no mundo vai te ensinar tudo, desculpa ser sincero! Os cursos são uma base, eles fornecem por volta de 30% do que você precisa aprender, o resto é com você, com dedicação e MUITA prática.

  • O que eu devo estudar?

    Java ou .NET? Angular ou React? Xamarin ou Flutter? A resposta é simples e direta: "Você já sabe o básico?"

    Se você ainda não sabe BEM o básico, ou seja, os fundamentos, OOP, SOLID, Clean Code, está perdendo tempo estudando Frameworks ou até coisas mais avançadas como Docker. Foque nos seus objetivos primeiro.
    Agora se você está indeciso sobre qual Framework estudar, a boa notícia é que o mercado neste momento está bem aquecido e você tem várias oportunidade. Desta forma o que levaríamos em conta para tomar esta decisão seria:

    • Já sei o básico
    • O Framework/Tecnologia tem mercado onde eu estou (região)
    • O Framework/Tecnologia é utilizado em uma empresa onde quero atual
    • O Framework/Tecnologia resolve meu problema
    • Eu gosto de utilizar o Framework/Tecnologia

  • Estou pronto para estudar no balta.io?

    Com certeza! O primeiro passo é começar e você pode fazer isto agora mesmo!

    Começar de graça

Ainda tem dúvidas?





Assine nosso Newsletter

Receba em primeira mão todas as nossas novidades.

Cadastrar


balta.io

Sobre

  • Como funciona?
  • Seja Premium
  • Agenda
  • Blog
  • Todos os cursos

Cursos

  • Frontend
  • Backend
  • Mobile
  • Fullstack

Suporte

  • Termos de uso
  • Privacidade
  • Cancelamento
  • Central de ajuda

Redes Sociais

  • Telegram
  • Facebook
  • Instagram
  • YouTube
  • Twitch
  • LinkedIn
  • Discord