GERADOR DE QR CODE NO ASP.NET CORE

Érik Thiago
6 min readSep 21, 2018

--

*imagem feita com base no freepik.com

Como gerar QR Code utilizando bibliotecas no ASP.NET CORE

Olá, leitores tudo bem? Estão prontos para mais um artigo sobre QR Codes? Desta vez, vamos costurar umas palavras sobre como gerar QR Codes no ASP.NET CORE utilizando bibliotecas instaladas via nuget. Bora lá? Acompanhe as linhas a seguir.

Primeiro, vamos a tecnologias utilizadas:

  • BootstrapPara estilizarmos nossas telinhas.
  • Razor PagesTecnologia utilizada para gerar paginas HTML5 no seridor via ASP.NET CORE.
  • ZxingBiblioteca que utilizei para gerar QR Codes. (Não limitado a esse tipo de código de barras. Gera vários outros tipos).
  • QRCoderOutra biblioteca que utilizei para gerar QR Codes. (Essa sim, focada somente em QR Code).

De posse dessas informações, bora codar!

Para começar, criei um projeto do tipo ASP.NET Core Web Application vazio, empty, e fui configurando o que era necessário. Não vou abordar como configurar porque o projeto tá no GitHub e lá está todinho configurado. Isso para ganhar tempo e focar no que realmente importa: como gerar QR Code.

Lembrando que você deve instalar as duas bibliotecas via nuget, ok?

Vamos primeiro abordar a Zxing, pois ela é mais simples, no contexto didático, ok?

Bom, ela é um pouco mais chata de se trabalhar porque ela necessita de algumas configurações para poder gerar o código de barras.

Ela trabalha com Bitmaps. A lógica retorna um bitmap para conversão em PNG. Só que, lembram que eu falei que a Zxing é um pouco chatinha? Pois é, a complicação vem agora, porque temos que configurar um TagHelper para ser renderizado na RazorPage, utilizando toda a lógica de conversão de imagem Bitmap para PNG. Pode soar complicado, mas isso vai ajudar muito e torna seu código na página Razor mais legível e essa foi a única forma que encontrei para gerar os QR Codes me utilizando dela

Para converter nosso Bitmap vamos criar uma classe para isso. Ela fará a mágica de converter a imagem e criar um TagHelper (Link para um artigo do saudoso Macoratti sobre o tema). De forma prática, criamos um recurso que poderá ser reutilizado por todo o projeto sem ficar duplicando código, apenas chamando o TagHelper como se fosse um atributo do HTML5 e passando o que precisamos para criar o elemento que precisamos na página, que nesse caso, seria uma imagem.

Ok, chega de tanta teoria, bora pro código. Segue o código da classe responsável pelo TagHelper:

// Nome da tag helper a ser chamada na razor page
[HtmlTargetElement("qrcodezxing")]
public class QRCodeTagHelperZXing : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
// Pega a url informada
var QrcodeContent = context.AllAttributes["content"].Value.ToString();
// Pega o texto da imagem
var alt = context.AllAttributes["alt"].Value.ToString();
// Tamanho da imagem
var width = 250; // width of the Qr Code
var height = 250; // height of the Qr Code
var margin = 0;

// Configurando o QR Code
var qrCodeWriter = new ZXing.BarcodeWriterPixelData
{
Format = ZXing.BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions { Height = height, Width = width, Margin = margin }
};
// Gerando o QR Code
var pixelData = qrCodeWriter.Write(QrcodeContent);

// criando um bitmap a partir dos dados de pixel brutos; se apenas as cores preto e branco forem usadas, não faz diferença
// que os dados de pixel são orientados para BGRA e o bitmap é inicializado com RGB
using (var bitmap = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb))
using (var ms = new MemoryStream())
{
var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
try
{
// assumimos que o passo da linha do bitmap está alinhado com 4 bytes multiplicado pela largura da imagem
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0,
pixelData.Pixels.Length);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
// salvar para transmitir como PNG
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
output.TagName = "img";
output.Attributes.Clear();
output.Attributes.Add("width", width);
output.Attributes.Add("height", height);
output.Attributes.Add("alt", alt);
output.Attributes.Add("src",
String.Format("data:image/png;base64,{0}", Convert.ToBase64String(ms.ToArray())));
}
}
}

O código parece grande, porém, em resumo o que é feito: criamos um QR Code a partir de um link enviado pelo controller. Esse cara, o controller, não havia sido mencionado ainda, certo? Bom, ele faz parte da lógica do ASP.NET CORE. Segue o código dele para que você entenda tudo que foi dito:

public IActionResult GeradorZXing()
{
string url = "https://medium.com/@erikthiago";
ViewBag.Message = url;
return View();
}

Com a lógica já configurada, basta chamar o TagHelper na página, conforme o código abaixo:

@{
ViewData["Title"] = "GeradorZXing";
}

<h2>GeradorZXing</h2>

<qrcodezxing alt="QR Code" content=@ViewBag.Message />

Pronto, criamos nosso primeiro QR Code! Simples, não? E olha que essa é umas das bibliotecas.

Agora vou mostrar uma outra biblioteca focada em geração de QR Codes, que é a QRCoder. Ela é bem legal, pois com ela podemos gerar alguns outros tipos de QR Code. Ou seja, além de links, podem ser utilizados para enviar SMS, WhatsApp, fazer ligações (SIM!! Ligar para números. É lindo isso), entre outras opções. Leia a documentação para saber mais. Aqui mostrarei uma outra opção dentre essas que é a de ligação, mas, no projeto tem exemplos de outras formas, ok?

Como a Zxing, podemos criar um TagHelper para reuso de código e facilitar. A lógica é a mesma, converter Bitmap para PNG. A diferença se dá pelo fato de utilizarmos a lógica de geração da biblioteca específica. Mais uma vez, no projeto já está tudo configurado, quero instigar vocês a ver como isso funciona no meu GitHub (:D, hahaha).

Gerar o código de barras com o QRCoder é muito simples. É de assustar, se comparar com a Zxing, pois não tem nada de complicação, a não ser que você queira.

Primeiro criamos uma classe que será responsável por concetrar a lógica principal da biblioteca para gerar os QR Codes que necessitamos. Eu criei uma classe para isso. E para a imagem ser renderizada, precisamos converter para bytearray. Os métodos de geração do QR Code e de conversão estão a seguir:

/// <summary>
/// Gerador de QR Code para uma string, url de um site
/// </summary>
/// <param name="url">Link de endereço de um site</param>
/// <returns>Retorna um QR Code em imagem</returns>
public static Bitmap GeneratedQRCode(string url)
{
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
Bitmap qrCodeImage = qrCode.GetGraphic(20);
return qrCodeImage;
}

/// <summary>
/// Converte a imagem do QR Code gerado em byte array
/// </summary>
/// <param name="img">A imagem do QR Code gerado</param>
/// <returns>A imagem convertida em byte array</returns>
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}

Segundo criamos no nosso controller a action responsável por chamar a página, e já passando pra página a imagem convertida em bytearray:

public IActionResult GeradorQRCoderSimples()
{
string url = "https://medium.com/@erikthiago";
Image image = GeneratorQRCoder.GeneratedQRCode(url);
byte[] byteArray = GeneratorQRCoder.ImageToByte2(image);
ViewBag.Message = byteArray;
return View();
}

E na tela respectiva:

@{
ViewData["Title"] = "GeradorQRCoderSimples";
}

<h2>GeradorQRCoderSimples</h2>

<img src="@String.Format("data:image/png;base64,{0}", Convert.ToBase64String(ViewBag.Message))" height="250" width="250" />

Famoso código delícia, é só implementar e ver a mágica funcionar. Me permitam ser um pouco teórico, só pra explicar o que aconteceu.

No controller chamamos as rotinas de configuração do QR Code e a conversão do Bitmap em bytearray e enviamos para a página. Na página, recebemos o bytearray, convertemos para PNG e renderizamos o QR Code em um elemento img do HTML5.

E como prometido, como gerar QR Code para ligação? Os passos continuam os mesmos, a única coisa que muda é chamar a rotina específica e criar a página que vai receber esse QR Code. O código para gerar é:

public IActionResult GeradorQRCodeLigacaoCelular()
{
Image image = GeneratorQRCoder.GeneratedQRCodeLigacaoCelular("+55DDDNºTELEFONE");
byte[] byteArray = GeneratorQRCoder.ImageToByte2(image);
ViewBag.Message = byteArray;
return View();
}

Pronto, simples não? Com qualquer uma das duas você vai conseguir gerar o QR Code. Depende do seu gosto, uma mais simples ou uma mais trabalhada. As duas são ótimas! Porém, a QRCoder tem opções a mais.

Críticas construtivas são muito bem vindas. O projeto está no GitHub. Como é aberto, caso queiram contribuir, à vontade!!

--

--

Érik Thiago
Érik Thiago

Written by Érik Thiago

Formado em Análise e Desenvolvimento de Sistemas. Brinca de tocar violão e guitarra. Adora C#, Azure, ASP.NET(CORE) e tecnologias que mudam o mundo para melhor.