Eventos

[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

No hay comentarios.:

Publicar un comentario

Epicalsoft — Superheroic Software Development Blog Designed by Templateism.com Copyright © 2014

Con tecnología de Blogger.