Eventos

[WP] Codigos QR

Hace poco me tope con la oportunidad de implementar una funcionalidad que me permitiera leer Códigos QR desde mi Windows Phone. Y sinceramente fue más sencillo de lo que esparaba gracias a una librería que encontré :). Para probarlo compartiré los pasos a seguir:

Paso 1

Usando NuGet Packages (haciendo click derecho sobre el Proyecto o la carpeta References -> Manage NuGet Packages...) descargamos la libreria ZXing.WP7 (la cual también es válida para WP8).


Paso 2

Definir la clase PhotoCameraLuminanceSource de la siguiente manera:

    public class PhotoCameraLuminanceSource : LuminanceSource
    {
        public byte[] PreviewBufferY { get; private set; }

        public PhotoCameraLuminanceSource(int width, int height) : base(width, height)
        {        
            PreviewBufferY = new byte[width * height];
        }

        public override sbyte[] Matrix
        {
            get { return (sbyte[])(Array)PreviewBufferY; }
        }

        public override sbyte[] getRow(int y, sbyte[] row)
        {
            if (row == null || row.Length < Width)
            {
                row = new sbyte[Width];
            }

            for (int i = 0; i < Height; i++)
                row[i] = (sbyte)PreviewBufferY[i * Width + y];

            return row;
        }
    }


Paso 3

Definir el XAML y el CSharp de la página (en mi caso la llame QRReaderPage) desde donde capturaremos el Código QR usando la cámara. En caso hagamos esto usando WP8 no hay que olvidarse de activar el ID_CAP_ISV_CAMERA en Capabilites del WMAppManifest.xml.

XAML

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Rectangle>
            <Rectangle.Fill>
                <VideoBrush x:Name="videoBrush" >
                    <VideoBrush.RelativeTransform>
                        <CompositeTransform x:Name="compositeTransform" CenterX="0.5" CenterY="0.5"/>
                    </VideoBrush.RelativeTransform>
                </VideoBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>


CSharp

    public partial class QRReaderPage : PhoneApplicationPage
    {
        private PhotoCamera photoCamera;
        private readonly DispatcherTimer dispatcherTimer = new DispatcherTimer();
        private QRCodeReader codeReader;

        public QRReaderPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            photoCamera = new PhotoCamera(CameraType.Primary);
            photoCamera.Initialized += (s, a) =>
            {
                codeReader = new QRCodeReader(); ;
                Dispatcher.BeginInvoke(() => { compositeTransform.Rotation = photoCamera.Orientation; });
            };
            videoBrush.SetSource(photoCamera);

            dispatcherTimer.Interval = TimeSpan.FromMilliseconds(250);
            dispatcherTimer.Tick += (o, arg) => ScanPreviewBuffer();
            dispatcherTimer.Start();
            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            dispatcherTimer.Stop();
        }

        private void ScanPreviewBuffer()
        {
            try
            {
                // crear un QRCodeReader
                int width = Convert.ToInt32(photoCamera.PreviewResolution.Width);
                int height = Convert.ToInt32(photoCamera.PreviewResolution.Height);
                PhotoCameraLuminanceSource _luminance = new PhotoCameraLuminanceSource(width, height);
                photoCamera.GetPreviewBufferY(_luminance.PreviewBufferY);
                // crear un bitmap
                var binBitmap = new com.google.zxing.BinaryBitmap(new HybridBinarizer(_luminance));
                // detectar y decodificar el bitmap
                var result = codeReader.decode(binBitmap);

                // hacer lo que queramos con el result
                NavigationService.Navigate(new Uri(string.Format("/Views/QRReaderResultPage.xaml?qrcode={0}", result.Text), UriKind.RelativeOrAbsolute));
            }
            catch { }
        }
    }


Y listo eso es lo unico que hay que hacer :)!

No hay comentarios.:

Publicar un comentario

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

Con tecnología de Blogger.