[WPF] ¿Como generar un Código QR y exportarlo en PNG?

En la presente publicación ejemplificaré como lograr estos objetivos ayudándonos de una librería llamada QrCode.Net la cual esta disponible para WinForms (no lo he probado) y WPF. Para este post he usado la versión 0.3 porque la 0.4 es Pre-release.

Con esta librería hay un par de formas de hacer esto: usando el control QrCodeControl o la clase QrEncoder.

QrCodeControl

Lo único que hay que hacer acá es dibujarlo correctamente en el XAML e ir actualizando su propiedad Text.

<Window x:Class="GenerateQR.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:qr="clr-namespace:Gma.QrCodeNet.Encoding.Windows.WPF;assembly=Gma.QrCodeNet.Encoding"
Title="[C#] ¿Cómo generar un Código QR y exportarlo en PNG?" Height="350" Width="525">
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtCode" Margin="6" TextChanged="txtCode_TextChanged"/>
<Button x:Name="btnExport" Grid.Column="2" Content="Exportar PNG" Margin="6" Click="btnExport_Click"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<qr:QrCodeImgControl Grid.Column="0" Margin="6" x:Name="qrControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Width="Auto" />
<Image Grid.Column="1" x:Name="imgQR" />
</Grid>
</Grid>
</Window>
        private void txtCode_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(txtCode.Text)) return;

//QrCodeImgControl
qrControl.Text = txtCode.Text;
}

QrEncoder

Para usar esta clase primero tenemos agregar las referencias a System.Drawing, PresentationCore y WindowsBase. Una vez agregadas las referencias continuamos:

        private Bitmap GetQRBitmap(string content)
{
var qrEncoder = new QrEncoder();
var code = qrEncoder.Encode(content);
var bitmapImage = new Bitmap(code.Matrix.Width, code.Matrix.Height);

for (int j = 0; j < code.Matrix.Height; j++)
for (int i = 0; i < code.Matrix.Width; i++)
bitmapImage.SetPixel(i, j, code.Matrix[i, j] ? System.Drawing.Color.Black : System.Drawing.Color.White);

return bitmapImage;
}

private BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();

return bitmapimage;
}
}

private void txtCode_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(txtCode.Text)) return;

//Image
var imageSource = BitmapToImageSource(GetQRBitmap(txtCode.Text));
this.imgQR.Width = imageSource.PixelWidth;
this.imgQR.Height = imageSource.PixelHeight;
this.imgQR.Source = imageSource;
this.imgQR.UpdateLayout();
}

Exportando el PNG

Aquí nos valemos de la clase PngBitmapEncoder y en este ejemplo estoy exportando el archivo en la misma carpeta del ejecutable para ser simples.

        private void btnExport_Click(object sender, RoutedEventArgs e)
{
string path = Guid.NewGuid().ToString() + ".png";

using (FileStream fileStream = new FileStream(path, FileMode.Create))
{
PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
pngBitmapEncoder.Frames.Add(BitmapFrame.Create((WriteableBitmap)qrControl.Source));
pngBitmapEncoder.Save(fileStream);
fileStream.Close();
}
}

CodePlex

Código fuente disponible en: CSharp -> GenerateQR

Agregue un comentario

Su dirección de correo no se hará público.