1. 程式人生 > >Unity基於ZXing.Net實現二維碼的製作

Unity基於ZXing.Net實現二維碼的製作

在Unity中,我們也可以實現二維碼的製作,這需要藉助Zxing的幫助,首先下載ZXing.Net。我這邊下載的是ZXing.Net 0.14.0.0 大家可以點選這個連結直接下載:http://zxingnet.codeplex.com/downloads/get/824664   下載解壓之後可以看到有一個unity資料夾,裡面包含了三個檔案。把資料夾拖到Unity工程中,在空物體上掛上下面這個指令碼,即可生成對應的二維碼。

using UnityEngine;
using System.Collections;
using ZXing;
using ZXing.QrCode;
using System;
using ZXing.Common;
using ZXing.Rendering;
using System.Collections.Generic;

public class BarcodeCam : MonoBehaviour
{
    public Texture2D encoded;



    void Start()
    {
        //設定二維碼大小
        encoded = new Texture2D(512, 512);
        //二維碼邊框
        BitMatrix BIT;
        //設定二維碼掃描結果
        string name = "http://www.baidu.com";

        Dictionary<EncodeHintType, object> hints = new Dictionary<EncodeHintType, object>();

        //設定編碼方式
        hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");

        BIT = new MultiFormatWriter().encode(name, BarcodeFormat.QR_CODE, 512, 512, hints);
        int width = BIT.Width;
        int height = BIT.Width;

        for (int x = 0; x < height; x++)
        {
            for (int y = 0; y < width; y++)
            {
                if (BIT[x, y])
                {
                    encoded.SetPixel(y, x, Color.black);
                }
                else
                {
                    encoded.SetPixel(y, x, Color.white);
                }

            }
        }
        encoded.Apply();

    }

    void OnGUI()
    {
        GUI.DrawTexture(new Rect(100, 100, 256, 256), encoded);
    }

}

對於其中的MultiFormatWriter,以及BitMatrix他們具體用法,我們在封裝好的dll中都可以找到。下面貼出他們的具體實現方法:

// Generated by .NET Reflector from C:\Users\Win8_CX01\Desktop\dddd\Assets\unity\zxing.unity.dll
namespace ZXing
{
    using System;
    using System.Collections.Generic;
    using ZXing.Aztec;
    using ZXing.Common;
    using ZXing.Datamatrix;
    using ZXing.OneD;
    using ZXing.PDF417;
    using ZXing.QrCode;
    
    public sealed class MultiFormatWriter : Writer
    {
        private static readonly IDictionary<BarcodeFormat, Func<Writer>> formatMap;
        
        static MultiFormatWriter()
        {
            Dictionary<BarcodeFormat, Func<Writer>> dictionary = new Dictionary<BarcodeFormat, Func<Writer>>();
            dictionary.Add(BarcodeFormat.EAN_8, () => new EAN8Writer());
            dictionary.Add(BarcodeFormat.EAN_13, () => new EAN13Writer());
            dictionary.Add(BarcodeFormat.UPC_A, () => new UPCAWriter());
            dictionary.Add(BarcodeFormat.QR_CODE, () => new QRCodeWriter());
            dictionary.Add(BarcodeFormat.CODE_39, () => new Code39Writer());
            dictionary.Add(BarcodeFormat.CODE_128, () => new Code128Writer());
            dictionary.Add(BarcodeFormat.ITF, () => new ITFWriter());
            dictionary.Add(BarcodeFormat.PDF_417, () => new PDF417Writer());
            dictionary.Add(BarcodeFormat.CODABAR, () => new CodaBarWriter());
            dictionary.Add(BarcodeFormat.MSI, () => new MSIWriter());
            dictionary.Add(BarcodeFormat.PLESSEY, () => new PlesseyWriter());
            dictionary.Add(BarcodeFormat.DATA_MATRIX, () => new DataMatrixWriter());
            dictionary.Add(BarcodeFormat.AZTEC, () => new AztecWriter());
            formatMap = dictionary;
        }
        
        public BitMatrix encode(string contents, BarcodeFormat format, int width, int height)
        {
            return this.encode(contents, format, width, height, null);
        }
        
        public BitMatrix encode(string contents, BarcodeFormat format, int width, int height, IDictionary<EncodeHintType, object> hints)
        {
            if (!formatMap.ContainsKey(format))
            {
                throw new ArgumentException("No encoder available for format " + format);
            }
            return formatMap[format]().encode(contents, format, width, height, hints);
        }
        
        public static ICollection<BarcodeFormat> SupportedWriters
        {
            get
            {
                return formatMap.Keys;
            }
        }
    }
}

namespace ZXing.Common
{
    using System;
    using System.Reflection;
    using System.Text;
    
    public sealed class BitMatrix
    {
        private readonly int[] bits;
        private readonly int height;
        private readonly int rowSize;
        private readonly int width;
        
        public BitMatrix(int dimension) : this(dimension, dimension)
        {
        }
        
        public BitMatrix(int width, int height)
        {
            if ((width < 1) || (height < 1))
            {
                throw new ArgumentException("Both dimensions must be greater than 0");
            }
            this.width = width;
            this.height = height;
            this.rowSize = (width + 0x1f) >> 5;
            this.bits = new int[this.rowSize * height];
        }
        
        private BitMatrix(int width, int height, int rowSize, int[] bits)
        {
            this.width = width;
            this.height = height;
            this.rowSize = rowSize;
            this.bits = bits;
        }
        
        public void clear()
        {
            int length = this.bits.Length;
            for (int i = 0; i < length; i++)
            {
                this.bits[i] = 0;
            }
        }
        
        public object Clone()
        {
            return new BitMatrix(this.width, this.height, this.rowSize, (int[]) this.bits.Clone());
        }
        
        public override bool Equals(object obj)
        {
            if (!(obj is BitMatrix))
            {
                return false;
            }
            BitMatrix matrix = (BitMatrix) obj;
            if (((this.width != matrix.width) || (this.height != matrix.height)) || ((this.rowSize != matrix.rowSize) || (this.bits.Length != matrix.bits.Length)))
            {
                return false;
            }
            for (int i = 0; i < this.bits.Length; i++)
            {
                if (this.bits[i] != matrix.bits[i])
                {
                    return false;
                }
            }
            return true;
        }
        
        public void flip(int x, int y)
        {
            int index = (y * this.rowSize) + (x >> 5);
            this.bits[index] ^= ((int) 1) << x;
        }
        
        public int[] getBottomRightOnBit()
        {
            int index = this.bits.Length - 1;
            while ((index >= 0) && (this.bits[index] == 0))
            {
                index--;
            }
            if (index < 0)
            {
                return null;
            }
            int num2 = index / this.rowSize;
            int num3 = (index % this.rowSize) << 5;
            int num4 = this.bits[index];
            int num5 = 0x1f;
            while ((num4 >> num5) == 0)
            {
                num5--;
            }
            num3 += num5;
            return new int[] { num3, num2 };
        }
        
        public int[] getEnclosingRectangle()
        {
            int width = this.width;
            int height = this.height;
            int num3 = -1;
            int num4 = -1;
            for (int i = 0; i < this.height; i++)
            {
                for (int j = 0; j < this.rowSize; j++)
                {
                    int num7 = this.bits[(i * this.rowSize) + j];
                    if (num7 != 0)
                    {
                        if (i < height)
                        {
                            height = i;
                        }
                        if (i > num4)
                        {
                            num4 = i;
                        }
                        if ((j * 0x20) < width)
                        {
                            int num8 = 0;
                            while ((num7 << (0x1f - num8)) == 0)
                            {
                                num8++;
                            }
                            if (((j * 0x20) + num8) < width)
                            {
                                width = (j * 0x20) + num8;
                            }
                        }
                        if (((j * 0x20) + 0x1f) > num3)
                        {
                            int num9 = 0x1f;
                            while ((num7 >> num9) == 0)
                            {
                                num9--;
                            }
                            if (((j * 0x20) + num9) > num3)
                            {
                                num3 = (j * 0x20) + num9;
                            }
                        }
                    }
                }
            }
            int num10 = num3 - width;
            int num11 = num4 - height;
            if ((num10 < 0) || (num11 < 0))
            {
                return null;
            }
            return new int[] { width, height, num10, num11 };
        }
        
        public override int GetHashCode()
        {
            int width = this.width;
            width = (0x1f * width) + this.width;
            width = (0x1f * width) + this.height;
            width = (0x1f * width) + this.rowSize;
            foreach (int num2 in this.bits)
            {
                width = (0x1f * width) + num2.GetHashCode();
            }
            return width;
        }
        
        public BitArray getRow(int y, BitArray row)
        {
            if ((row == null) || (row.Size < this.width))
            {
                row = new BitArray(this.width);
            }
            else
            {
                row.clear();
            }
            int num = y * this.rowSize;
            for (int i = 0; i < this.rowSize; i++)
            {
                row.setBulk(i << 5, this.bits[num + i]);
            }
            return row;
        }
        
        public int[] getTopLeftOnBit()
        {
            int index = 0;
            while ((index < this.bits.Length) && (this.bits[index] == 0))
            {
                index++;
            }
            if (index == this.bits.Length)
            {
                return null;
            }
            int num2 = index / this.rowSize;
            int num3 = (index % this.rowSize) << 5;
            int num4 = this.bits[index];
            int num5 = 0;
            while ((num4 << (0x1f - num5)) == 0)
            {
                num5++;
            }
            num3 += num5;
            return new int[] { num3, num2 };
        }
        
        public void rotate180()
        {
            int width = this.Width;
            int height = this.Height;
            BitArray row = new BitArray(width);
            BitArray array2 = new BitArray(width);
            for (int i = 0; i < ((height + 1) / 2); i++)
            {
                row = this.getRow(i, row);
                array2 = this.getRow((height - 1) - i, array2);
                row.reverse();
                array2.reverse();
                this.setRow(i, array2);
                this.setRow((height - 1) - i, row);
            }
        }
        
        public void setRegion(int left, int top, int width, int height)
        {
            if ((top < 0) || (left < 0))
            {
                throw new ArgumentException("Left and top must be nonnegative");
            }
            if ((height < 1) || (width < 1))
            {
                throw new ArgumentException("Height and width must be at least 1");
            }
            int num = left + width;
            int num2 = top + height;
            if ((num2 > this.height) || (num > this.width))
            {
                throw new ArgumentException("The region must fit inside the matrix");
            }
            for (int i = top; i < num2; i++)
            {
                int num4 = i * this.rowSize;
                for (int j = left; j < num; j++)
                {
                    this.bits[num4 + (j >> 5)] |= ((int) 1) << j;
                }
            }
        }
        
        public void setRow(int y, BitArray row)
        {
            Array.Copy(row.Array, 0, this.bits, y * this.rowSize, this.rowSize);
        }
        
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder(this.height * (this.width + 1));
            for (int i = 0; i < this.height; i++)
            {
                for (int j = 0; j < this.width; j++)
                {
                    builder.Append(this[j, i] ? "X " : "  ");
                }
                builder.AppendLine("");
            }
            return builder.ToString();
        }
        
        public int Dimension
        {
            get
            {
                if (this.width != this.height)
                {
                    throw new ArgumentException("Can't call getDimension() on a non-square matrix");
                }
                return this.width;
            }
        }
        
        public int Height
        {
            get
            {
                return this.height;
            }
        }
        
        public bool this[int x, int y]
        {
            get
            {
                int index = (y * this.rowSize) + (x >> 5);
                return (((this.bits[index] >> x) & 1) != 0);
            }
            set
            {
                if (value)
                {
                    int index = (y * this.rowSize) + (x >> 5);
                    this.bits[index] |= ((int) 1) << x;
                }
            }
        }
        
        public int Width
        {
            get
            {
                return this.width;
            }
        }
    }
}