酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Xamarin.FormsでZXingを使ってQRコード/バーコードを生成する

メモです。Xamarin.FormsでZXingを使ってQRコード/バーコードを生成しました。

NugetにはZXing for Xamarin.Formsと書かれたものがあったのですが、どうもPCL側にライブラリを追加したらバーコードが生成できるというものではなかったみたいです。

今回、DependencyServiceを使ってみました。

f:id:ch3cooh393:20170110172416p:plain

ZXingをインストールする

パッケージを追加します。

f:id:ch3cooh393:20170110165645p:plain

iOS側のプロジェクトのパッケージにZXing.Net.Mobileが追加されました。

f:id:ch3cooh393:20170110165517p:plain

QRコードを生成してImageに表示する

テキストからバーコードを生成する処理

IBarcodeUtilitiy.cs

QRCodeMaker(PCL側)にインターフェイスを定義しておきます。

using System.IO;

namespace QRCodeMaker
{
    public interface IBarcodeUtilitiy
    {
        Stream ConvertImageStream(string text, int width = 300, int height = 300);
    }
}

BarcodeUtilitiy.cs

iOSのプロジェクト側に実装します。

using System;
using System.IO;
using ZXing.Mobile;

[assembly: Xamarin.Forms.Dependency(typeof(QRCodeMaker.iOS.BarcodeUtilitiy))]
namespace QRCodeMaker.iOS
{
    public class BarcodeUtilitiy : IBarcodeUtilitiy
    {
        public Stream ConvertImageStream(string text, int width = 300, int height = 300)
        {
            var barcodeWriter = new BarcodeWriter
            {
                Format = ZXing.BarcodeFormat.QR_CODE,
                Options = new ZXing.Common.EncodingOptions
                {
                    Width = width,
                    Height = height,
                    Margin = 1
                }
            };
            barcodeWriter.Renderer = new BitmapRenderer();
            var bitmap = barcodeWriter.Write(text);
            var stream = bitmap.AsPNG().AsStream();
            stream.Position = 0;

            return stream;
        }
    }
}

これでPCL側のプロジェクトでは、DependencyService.Get<IBarcodeUtilitiy>().ConvertImageStream("test");でバーコードを生成することができます。

画面を表示する

QRCodeMakerPage.xaml

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:QRCodeMaker" 
    x:Class="QRCodeMaker.QRCodeMakerPage">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness"
            iOS="0,20,0,0" />
    </ContentPage.Padding>
    
    <StackLayout Orientation="Vertical">
        <Label Text="Welcome to Xamarin Forms!" 
            VerticalOptions="Center" 
            HorizontalOptions="Center" />

        <Button Text="Generate" Clicked="generateAction" />
        
        <Image x:Name="imageView" 
            BackgroundColor="Aqua"
            HeightRequest="300"
            WidthRequest="300" />
    </StackLayout>
</ContentPage>

QRCodeMakerPage.xaml.cs

using System;
using System.IO;
using Xamarin.Forms;

namespace QRCodeMaker
{
    public partial class QRCodeMakerPage : ContentPage
    {
        public QRCodeMakerPage()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            imageView.Source = ImageSource.FromStream(() =>
            {
                return DependencyService.Get<IBarcodeUtilitiy>().ConvertImageStream("test");
            });
        }

        // ボタンが押される度にランダムなバーコードを生成する
        void generateAction(object sender, System.EventArgs e)
        {
            var text = DateTime.UtcNow.Ticks.ToString();
            imageView.Source = ImageSource.FromStream(() =>
            {
                return DependencyService.Get<IBarcodeUtilitiy>().ConvertImageStream(text);
            });
        }
    }
}

実行結果

タップする度にバーコードを生成しています。

f:id:ch3cooh393:20170110171718g:plain