示例#1
0
      public void test()
      {
         var qrCode = new QRCode();

         // First, test simple setters and getters.
         // We use numbers of version 7-H.
         qrCode.Mode = Mode.BYTE;
         qrCode.ECLevel = ErrorCorrectionLevel.H;
         qrCode.Version = Version.getVersionForNumber(7);
         qrCode.MaskPattern = 3;

         Assert.AreEqual(Mode.BYTE, qrCode.Mode);
         Assert.AreEqual(ErrorCorrectionLevel.H, qrCode.ECLevel);
         Assert.AreEqual(7, qrCode.Version.VersionNumber);
         Assert.AreEqual(3, qrCode.MaskPattern);

         // Prepare the matrix.
         var matrix = new ByteMatrix(45, 45);
         // Just set bogus zero/one values.
         for (int y = 0; y < 45; ++y)
         {
            for (int x = 0; x < 45; ++x)
            {
               matrix.set(x, y, (y + x) % 2 == 1);
            }
         }

         // Set the matrix.
         qrCode.Matrix = matrix;
         Assert.AreEqual(matrix, qrCode.Matrix);
      }
示例#2
0
 // The mask penalty calculation is complicated.  See Table 21 of JISX0510:2004 (p.45) for details.
 // Basically it applies four rules and summate all penalties.
 private static int calculateMaskPenalty(ByteMatrix matrix)
 {
    return MaskUtil.applyMaskPenaltyRule1(matrix)
            + MaskUtil.applyMaskPenaltyRule2(matrix)
            + MaskUtil.applyMaskPenaltyRule3(matrix)
            + MaskUtil.applyMaskPenaltyRule4(matrix);
 }
示例#3
0
 public void testApplyMaskPenaltyRule2()
 {
    var matrix = new ByteMatrix(1, 1);
    matrix.set(0, 0, 0);
    Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule2(matrix));
    matrix = new ByteMatrix(2, 2);
    matrix.set(0, 0, 0);
    matrix.set(1, 0, 0);
    matrix.set(0, 1, 0);
    matrix.set(1, 1, 1);
    Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule2(matrix));
    matrix = new ByteMatrix(2, 2);
    matrix.set(0, 0, 0);
    matrix.set(1, 0, 0);
    matrix.set(0, 1, 0);
    matrix.set(1, 1, 0);
    Assert.AreEqual(3, MaskUtil.applyMaskPenaltyRule2(matrix));
    matrix = new ByteMatrix(3, 3);
    matrix.set(0, 0, 0);
    matrix.set(1, 0, 0);
    matrix.set(2, 0, 0);
    matrix.set(0, 1, 0);
    matrix.set(1, 1, 0);
    matrix.set(2, 1, 0);
    matrix.set(0, 2, 0);
    matrix.set(1, 2, 0);
    matrix.set(2, 2, 0);
    // Four instances of 2x2 blocks.
    Assert.AreEqual(3*4, MaskUtil.applyMaskPenaltyRule2(matrix));
 }
示例#4
0
 public void testApplyMaskPenaltyRule1()
 {
    {
       ByteMatrix matrix = new ByteMatrix(4, 1);
       matrix.set(0, 0, 0);
       matrix.set(1, 0, 0);
       matrix.set(2, 0, 0);
       matrix.set(3, 0, 0);
       Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule1(matrix));
    }
    {  // Horizontal.
       ByteMatrix matrix = new ByteMatrix(6, 1);
       matrix.set(0, 0, 0);
       matrix.set(1, 0, 0);
       matrix.set(2, 0, 0);
       matrix.set(3, 0, 0);
       matrix.set(4, 0, 0);
       matrix.set(5, 0, 1);
       Assert.AreEqual(3, MaskUtil.applyMaskPenaltyRule1(matrix));
       matrix.set(5, 0, 0);
       Assert.AreEqual(4, MaskUtil.applyMaskPenaltyRule1(matrix));
    }
    {  // Vertical.
       ByteMatrix matrix = new ByteMatrix(1, 6);
       matrix.set(0, 0, 0);
       matrix.set(0, 1, 0);
       matrix.set(0, 2, 0);
       matrix.set(0, 3, 0);
       matrix.set(0, 4, 0);
       matrix.set(0, 5, 1);
       Assert.AreEqual(3, MaskUtil.applyMaskPenaltyRule1(matrix));
       matrix.set(0, 5, 0);
       Assert.AreEqual(4, MaskUtil.applyMaskPenaltyRule1(matrix));
    }
 }
示例#5
0
 // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
 // success, store the result in "matrix" and return true.
 //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
 //ORIGINAL LINE: static void buildMatrix(com.google.zxing.common.BitArray dataBits, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ecLevel, com.google.zxing.qrcode.decoder.Version version, int maskPattern, ByteMatrix matrix) throws com.google.zxing.WriterException
 internal static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, Version version, int maskPattern, ByteMatrix matrix)
 {
     clearMatrix(matrix);
     embedBasicPatterns(version, matrix);
     // Type information appear with any version.
     embedTypeInfo(ecLevel, maskPattern, matrix);
     // Version info appear if version >= 7.
     maybeEmbedVersionInfo(version, matrix);
     // Data should be embedded at end.
     embedDataBits(dataBits, maskPattern, matrix);
 }
示例#6
0
        public static BitMatrix Encode(string content, ErrorCorrectionLevel ecLevel)
        {
			QRCodeInternal qrInternal;
			BitVector headerAndDataBits = DataEncodeUsingReferenceImplementation(content, ecLevel, out qrInternal);
			
			// Step 6: Interleave data bits with error correction code.
			BitVector finalBits = new BitVector();
			EncoderInternal.interleaveWithECBytes(headerAndDataBits, qrInternal.NumTotalBytes, qrInternal.NumDataBytes, qrInternal.NumRSBlocks, finalBits);
			
			// Step 7: Choose the mask pattern and set to "QRCodeInternal".
			ByteMatrix matrix = new ByteMatrix(qrInternal.MatrixWidth, qrInternal.MatrixWidth);
			int MaskPattern = EncoderInternal.chooseMaskPattern(finalBits, qrInternal.EcLevelInternal, qrInternal.Version, matrix);
			
			// Step 8.  Build the matrix and set it to "QRCodeInternal".
			MatrixUtil.buildMatrix(finalBits, qrInternal.EcLevelInternal, qrInternal.Version, MaskPattern, matrix);
			return matrix.ToBitMatrix();
        }
示例#7
0
        public void testBuildMatrix()
        {
            // From http://www.swetake.com/qr/qr7.html
            String expected =
                " 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1\n" +
                " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" +
                " 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1\n" +
                " 1 0 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1\n" +
                " 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1\n" +
                " 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1\n" +
                " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
                " 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0\n" +
                " 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0\n" +
                " 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0\n" +
                " 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0\n" +
                " 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0\n" +
                " 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1\n" +
                " 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1\n" +
                " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0\n" +
                " 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0\n" +
                " 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1\n" +
                " 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0\n" +
                " 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 0 0\n" +
                " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0\n" +
                " 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 0\n";

            int[]    bytes = { 32,  65, 205,  69,  41, 220,  46, 128, 236,
                               42,    159,  74, 221, 244, 169, 239, 150, 138,
                               70,    237,  85, 224,  96,  74, 219, 61 };
            BitArray bits = new BitArray();

            foreach (char c in bytes)
            {
                bits.appendBits(c, 8);
            }
            ByteMatrix matrix = new ByteMatrix(21, 21);

            MatrixUtil.buildMatrix(bits,
                                   ErrorCorrectionLevel.H,
                                   Version.getVersionForNumber(1), // Version 1
                                   3,                              // Mask pattern 3
                                   matrix);
            Assert.AreEqual(expected, matrix.ToString());
        }
        private void GenQR(string ssconfig)
        {
            int dpi_mul = Util.Utils.GetDpiMul();
            int width   = 350 * dpi_mul / 4;

            if (txtLink.Focused)
            {
                string     qrText    = ssconfig;
                QRCode     code      = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
                ByteMatrix m         = code.Matrix;
                int        blockSize = Math.Max(width / (m.Width + 2), 1);
                Bitmap     drawArea  = new Bitmap(((m.Width + 2) * blockSize), ((m.Height + 2) * blockSize));
                using (Graphics g = Graphics.FromImage(drawArea))
                {
                    g.Clear(Color.White);
                    using (Brush b = new SolidBrush(Color.Black))
                    {
                        for (int row = 0; row < m.Width; row++)
                        {
                            for (int col = 0; col < m.Height; col++)
                            {
                                if (m[row, col] != 0)
                                {
                                    g.FillRectangle(b, blockSize * (row + 1), blockSize * (col + 1),
                                                    blockSize, blockSize);
                                }
                            }
                        }
                    }
                    Bitmap ngnl = Resources.ngnl;
                    int    div = 13, div_l = 5, div_r = 8;
                    int    l = (m.Width * div_l + div - 1) / div * blockSize, r = (m.Width * div_r + div - 1) / div * blockSize;
                    g.DrawImage(ngnl, new Rectangle(l + blockSize, l + blockSize, r - l, r - l));
                }
                picQRcode.Image   = drawArea;
                picQRcode.Visible = true;
                _modifiedConfiguration.isHideTips = true;
            }
            else
            {
                //PictureQRcode.Visible = false;
                DrawLogo(picQRcode.Width);
            }
        }
示例#9
0
 private static void embedPositionDetectionPattern(int xStart, int yStart, ByteMatrix matrix)
 {
     // We know the width and height.
     if (POSITION_DETECTION_PATTERN[0].Length != 7 || POSITION_DETECTION_PATTERN.Length != 7)
     {
         throw new WriterException("Bad position detection pattern");
     }
     for (int y = 0; y < 7; ++y)
     {
         for (int x = 0; x < 7; ++x)
         {
             if (!isEmpty(matrix[yStart + y, xStart + x]))
             {
                 throw new WriterException();
             }
             matrix[yStart + y, xStart + x] = (sbyte)POSITION_DETECTION_PATTERN[y][x];
         }
     }
 }
示例#10
0
 /// <summary>
 /// Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
 /// penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a
 /// penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.
 /// </summary>
 internal static int applyMaskPenaltyRule2(ByteMatrix matrix)
 {
     int penalty = 0;
     sbyte[][] array = matrix.Array;
     int width = matrix.Width;
     int height = matrix.Height;
     for (int y = 0; y < height - 1; y++)
     {
       for (int x = 0; x < width - 1; x++)
       {
     int value = array[y][x];
     if (value == array[y][x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1])
     {
       penalty++;
     }
       }
     }
     return N2 * penalty;
 }
示例#11
0
        //普通二维码
        private void btnEncode_Click(object sender, EventArgs e)
        {
            labShow.Text = "";
            string content = txtMsg.Text.Trim();

            if (String.IsNullOrEmpty(content))
            {
                MessageBox.Show("请输入原文!");
                return;
            }
            try
            {
                MultiFormatWriter writer = new MultiFormatWriter();

                ByteMatrix matrix = writer.encode(content, BarcodeFormat.QR_CODE, 300, 300);
                Bitmap     img    = matrix.ToBitmap();

                //将img转换成bmp格式,否则后面无法创建 Graphics对象
                Bitmap bmpimg = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(bmpimg))
                {
                    g.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    g.DrawImage(img, 0, 0);
                }
                Graphics MyGraphic = Graphics.FromImage(bmpimg);
                float    x         = pictureBox1.Width / 2 - 50;
                float    y         = pictureBox1.Height - 30;
                MyGraphic.DrawString(content, this.Font, new SolidBrush(Color.Black), x, y);

                pictureBox1.Image = bmpimg;

                //自动保存图片到默认目录
                //string filename = Environment.CurrentDirectory + "\\QR" + DateTime.Now.Ticks.ToString() + ".jpg";
                //bitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
                //labShow.Text = "图片已保存到:" + filename;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
示例#12
0
 private static void embedTimingPatterns(ByteMatrix matrix)
 {
     // -8 is for skipping position detection patterns (size 7), and two horizontal/vertical
     // separation patterns (size 1). Thus, 8 = 7 + 1.
     for (int i = 8; i < matrix.Width - 8; ++i)
     {
         int bit = (i + 1) % 2;
         // Horizontal line.
         if (isEmpty(matrix.get(i, 6)))
         {
             matrix.set(i, 6, bit);
         }
         // Vertical line.
         if (isEmpty(matrix.get(6, i)))
         {
             matrix.set(6, i, bit);
         }
     }
 }
示例#13
0
 // Note that we cannot unify the function with embedPositionDetectionPattern() despite they are
 // almost identical, since we cannot write a function that takes 2D arrays in different sizes in
 // C/C++. We should live with the fact.
 private static void embedPositionAdjustmentPattern(int xStart, int yStart, ByteMatrix matrix)
 {
     // We know the width and height.
     if (POSITION_ADJUSTMENT_PATTERN[0].Length != 5 || POSITION_ADJUSTMENT_PATTERN.Length != 5)
     {
         throw new WriterException("Bad position adjustment");
     }
     for (int y = 0; y < 5; ++y)
     {
         for (int x = 0; x < 5; ++x)
         {
             if (!isEmpty(matrix[yStart + y, xStart + x]))
             {
                 throw new WriterException();
             }
             matrix[yStart + y, xStart + x] = (sbyte)POSITION_ADJUSTMENT_PATTERN[y][x];
         }
     }
 }
示例#14
0
        /// <summary>
        /// 获取二维码位图
        /// </summary>
        /// <param name="ngnl">原始logo</param>
        /// <param name="width">二维码显示多大,默认350,数字越大则图越大</param>
        /// <returns></returns>
        public Bitmap GetQR(int width = 350, Bitmap ngnl = null)
        {
            if (buff == null || buff == "")
            {
                return(null);
            }
            if (ngnl == null)
            {
                ngnl = new Bitmap(10, 10);
            }
            int dpi_mul = GetDpiMul();

            width = width * dpi_mul / 4;
            string     qrText    = buff;
            QRCode     code      = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
            ByteMatrix m         = code.Matrix;
            int        blockSize = Math.Max(width / (m.Width + 2), 1);
            Bitmap     drawArea  = new Bitmap(((m.Width + 2) * blockSize), ((m.Height + 2) * blockSize));

            using (Graphics g = Graphics.FromImage(drawArea))
            {
                g.Clear(Color.White);
                using (Brush b = new SolidBrush(Color.Black))
                {
                    for (int row = 0; row < m.Width; row++)
                    {
                        for (int col = 0; col < m.Height; col++)
                        {
                            if (m[row, col] != 0)
                            {
                                g.FillRectangle(b, blockSize * (row + 1), blockSize * (col + 1),
                                                blockSize, blockSize);
                            }
                        }
                    }
                }
                int div = 13, div_l = 5, div_r = 8;
                int l = (m.Width * div_l + div - 1) / div * blockSize, r = (m.Width * div_r + div - 1) / div * blockSize;
                g.DrawImage(ngnl, new Rectangle(l + blockSize, l + blockSize, r - l, r - l));
            }
            return(drawArea);
        }
示例#15
0
        public static Bitmap Create(string content, Image centralImage)
        {
            //构造二维码写码器
            MultiFormatWriter mutiWriter = new com.google.zxing.MultiFormatWriter();
            Hashtable         hint       = new Hashtable();

            hint.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
            hint.Add(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H);
            //生成二维码
            ByteMatrix bm  = mutiWriter.encode(content, com.google.zxing.BarcodeFormat.QR_CODE, 300, 300, hint);
            Bitmap     img = bm.ToBitmap();

            //要插入到二维码中的图片
            Image middlImg = centralImage;
            //获取二维码实际尺寸(去掉二维码两边空白后的实际尺寸)
            //  System.Drawing.Size realSize = mutiWriter.GetEncodeSize(content, com.google.zxing.BarcodeFormat.QR_CODE, 300, 300);
            var realSize = mutiWriter.encode(content, com.google.zxing.BarcodeFormat.QR_CODE, 300, 300);
            //计算插入图片的大小和位置
            int middleImgW = Math.Min((int)(realSize.Width / 3.5), middlImg.Width);
            int middleImgH = Math.Min((int)(realSize.Height / 3.5), middlImg.Height);
            int middleImgL = (img.Width - middleImgW) / 2;
            int middleImgT = (img.Height - middleImgH) / 2;

            //将img转换成bmp格式,否则后面无法创建 Graphics对象
            Bitmap bmpimg = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            using (Graphics g = Graphics.FromImage(bmpimg))
            {
                g.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.DrawImage(img, 0, 0);
            }

            //在二维码中插入图片
            System.Drawing.Graphics MyGraphic = System.Drawing.Graphics.FromImage(bmpimg);
            //白底
            MyGraphic.FillRectangle(Brushes.White, middleImgL, middleImgT, middleImgW, middleImgH);
            MyGraphic.DrawImage(middlImg, middleImgL, middleImgT, middleImgW, middleImgH);

            return(bmpimg);
        }
示例#16
0
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                MultiFormatWriter mutiWriter = new com.google.zxing.MultiFormatWriter();
                //ByteMatrix bm = mutiWriter.encode(txtMsg.Text, com.google.zxing.BarcodeFormat.QR_CODE, 300, 300);//二维码
                ByteMatrix bm  = mutiWriter.encode(txtMsg.Text, com.google.zxing.BarcodeFormat.EAN_8, 300, 300);//8位数字
                Bitmap     img = bm.ToBitmap();

                pictureBox1.Width  = img.Width;
                pictureBox1.Height = img.Height;
                pictureBox1.Image  = img;

                //自动保存图片到当前目录
                string filename = System.Environment.CurrentDirectory + "\\QR" + DateTime.Now.Ticks.ToString() + ".jpg";
                img.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
                lbshow.Text = "图片已保存到:" + filename;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
 // Note that we cannot unify the function with EmbedPositionDetectionPattern() despite they are
 // almost identical, since we cannot write a function that takes 2D arrays in different sizes in
 // C/C++. We should live with the fact.
 private static void EmbedPositionAdjustmentPattern(int xStart, int yStart,
                                                    ByteMatrix matrix)
 {
     // We know the width and height.
     if (POSITION_ADJUSTMENT_PATTERN[0].Length != 5 || POSITION_ADJUSTMENT_PATTERN.GetLength(0) != 5)
     {
         throw new WriterException("Bad position adjustment");
     }
     for (var y = 0; y < 5; ++y)
     {
         for (var x = 0; x < 5; ++x)
         {
             if (!IsEmpty(matrix.Get(xStart + x, yStart + y)))
             {
                 throw new WriterException();
             }
             matrix.Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);
         }
     }
 }
 private static void EmbedPositionDetectionPattern(int xStart, int yStart,
                                                   ByteMatrix matrix)
 {
     // We know the width and height.
     if (POSITION_DETECTION_PATTERN[0].Length != 7 || POSITION_DETECTION_PATTERN.GetLength(0) != 7)
     {
         throw new WriterException("Bad position detection pattern");
     }
     for (var y = 0; y < 7; ++y)
     {
         for (var x = 0; x < 7; ++x)
         {
             if (!IsEmpty(matrix.Get(xStart + x, yStart + y)))
             {
                 throw new WriterException();
             }
             matrix.Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
         }
     }
 }
示例#19
0
        /// <summary>
        /// Convert the ByteMatrix to BitMatrix.
        /// </summary>
        /// <param name="matrix">The input matrix.</param>
        /// <param name="reqWidth">The requested width of the image (in pixels) with the Datamatrix code</param>
        /// <param name="reqHeight">The requested height of the image (in pixels) with the Datamatrix code</param>
        /// <returns>The output matrix.</returns>
        private static BitMatrix convertByteMatrixToBitMatrix(ByteMatrix matrix, int reqWidth, int reqHeight)
        {
            var matrixWidth  = matrix.Width;
            var matrixHeight = matrix.Height;
            var outputWidth  = Math.Max(reqWidth, matrixWidth);
            var outputHeight = Math.Max(reqHeight, matrixHeight);

            int multiple = Math.Min(outputWidth / matrixWidth, outputHeight / matrixHeight);

            int leftPadding = (outputWidth - (matrixWidth * multiple)) / 2;
            int topPadding  = (outputHeight - (matrixHeight * multiple)) / 2;

            BitMatrix output;

            // remove padding if requested width and height are too small
            if (reqHeight < matrixHeight || reqWidth < matrixWidth)
            {
                leftPadding = 0;
                topPadding  = 0;
                output      = new BitMatrix(matrixWidth, matrixHeight);
            }
            else
            {
                output = new BitMatrix(reqWidth, reqHeight);
            }

            output.clear();
            for (int inputY = 0, outputY = topPadding; inputY < matrixHeight; inputY++, outputY += multiple)
            {
                // Write the contents of this row of the bytematrix
                for (int inputX = 0, outputX = leftPadding; inputX < matrixWidth; inputX++, outputX += multiple)
                {
                    if (matrix[inputX, inputY] == 1)
                    {
                        output.setRegion(outputX, outputY, multiple, multiple);
                    }
                }
            }

            return(output);
        }
示例#20
0
        /// <summary>
        /// Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
        /// penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a
        /// penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.
        /// </summary>
        internal static int applyMaskPenaltyRule2(ByteMatrix matrix)
        {
            int penalty = 0;

            sbyte[][] array  = matrix.Array;
            int       width  = matrix.Width;
            int       height = matrix.Height;

            for (int y = 0; y < height - 1; y++)
            {
                for (int x = 0; x < width - 1; x++)
                {
                    int value = array[y][x];
                    if (value == array[y][x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1])
                    {
                        penalty++;
                    }
                }
            }
            return(N2 * penalty);
        }
        public static ByteMatrix CreateRawQR(byte[] rawData, ErrorCorrectionLevel errorCorrectionLevel)
        {
            int versionNumber = GetSmallestVersion(rawData.Length, errorCorrectionLevel);
            ZXing.QrCode.Internal.Version version = ZXing.QrCode.Internal.Version.getVersionForNumber(versionNumber);

            BitArray dataBits = new BitArray();
            foreach (byte b in rawData)
                dataBits.appendBits(b, 8);

            ZXing.QrCode.Internal.Version.ECBlocks ecBlocks = version.getECBlocksForLevel(errorCorrectionLevel);
            int bytesLength = version.TotalCodewords - ecBlocks.TotalECCodewords;
            terminateBits(bytesLength, dataBits);

            BitArray resultBits = interleaveWithECBytes(dataBits, version.TotalCodewords, bytesLength, ecBlocks.NumBlocks);

            ByteMatrix matrix = new ByteMatrix(version.DimensionForVersion, version.DimensionForVersion);
            int maskPattern = chooseMaskPattern(resultBits, errorCorrectionLevel, version, matrix);

            MatrixUtil.buildMatrix(resultBits, errorCorrectionLevel, version, maskPattern, matrix);
            return matrix;
        }
示例#22
0
        // Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
        // penalty to them.
        public static int applyMaskPenaltyRule2(ByteMatrix matrix)
        {
            int penalty = 0;

            sbyte[][] array  = matrix.getArray();
            int       width  = matrix.width();
            int       height = matrix.height();

            for (int y = 0; y < height - 1; ++y)
            {
                for (int x = 0; x < width - 1; ++x)
                {
                    int value = array[y][x];
                    if (value == array[y][x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1])
                    {
                        penalty += 3;
                    }
                }
            }
            return(penalty);
        }
示例#23
0
        private void GenQR(string ssconfig)
        {
            int dpi_mul = Util.Utils.GetDpiMul();
            int width   = Math.Min(PictureQRcode.Width, PictureQRcode.Height) * 4 / 4;

            try
            {
                string     qrText    = ssconfig;
                QRCode     code      = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
                ByteMatrix m         = code.Matrix;
                int        blockSize = Math.Max(width / (m.Width + 2), 1);
                Bitmap     drawArea  = new Bitmap(((m.Width + 2) * blockSize), ((m.Height + 2) * blockSize));
                using (Graphics g = Graphics.FromImage(drawArea))
                {
                    g.Clear(Color.White);
                    using (Brush b = new SolidBrush(Color.Black))
                    {
                        for (int row = 0; row < m.Width; row++)
                        {
                            for (int col = 0; col < m.Height; col++)
                            {
                                if (m[row, col] != 0)
                                {
                                    g.FillRectangle(b, blockSize * (row + 1), blockSize * (col + 1),
                                                    blockSize, blockSize);
                                }
                            }
                        }
                    }
                    Bitmap ngnl = Resources.ngnl;
                    int    div = 13, div_l = 5, div_r = 8;
                    int    l = (m.Width * div_l + div - 1) / div * blockSize, r = (m.Width * div_r + div - 1) / div * blockSize;
                    g.DrawImage(ngnl, new Rectangle(l + blockSize, l + blockSize, r - l, r - l));
                }
                PictureQRcode.Image = drawArea;
            }
            catch
            {
            }
        }
        public void testApplyMaskPenaltyRule4()
        {
            // Dark cell ratio = 0%
            var matrix = new ByteMatrix(1, 1);

            matrix.set(0, 0, 0);
            Assert.AreEqual(100, MaskUtil.applyMaskPenaltyRule4(matrix));
            // Dark cell ratio = 5%
            matrix = new ByteMatrix(2, 1);
            matrix.set(0, 0, 0);
            matrix.set(0, 0, 1);
            Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule4(matrix));
            // Dark cell ratio = 66.67%
            matrix = new ByteMatrix(6, 1);
            matrix.set(0, 0, 0);
            matrix.set(1, 0, 1);
            matrix.set(2, 0, 1);
            matrix.set(3, 0, 1);
            matrix.set(4, 0, 1);
            matrix.set(5, 0, 0);
            Assert.AreEqual(30, MaskUtil.applyMaskPenaltyRule4(matrix));
        }
示例#25
0
        // Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give
        // penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance. Examples:
        // -   0% => 100
        // -  40% =>  20
        // -  45% =>  10
        // -  50% =>   0
        // -  55% =>  10
        // -  55% =>  20
        // - 100% => 100
        internal static int applyMaskPenaltyRule4(ByteMatrix matrix)
        {
            int numDarkCells = 0;
            int width        = matrix.Width;
            int height       = matrix.Height;

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    if (matrix[x, y] == 1)
                    {
                        numDarkCells += 1;
                    }
                }
            }
            int    numTotalCells = matrix.Height * matrix.Width;
            double darkRatio     = (double)numDarkCells / numTotalCells;

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            return(System.Math.Abs((int)(darkRatio * 100 - 50)) / 5 * 10);
        }
示例#26
0
        // Note that the input matrix uses 0 == white, 1 == black, while the output matrix uses
        // 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
        private static BitMatrix renderResult(QRCode code, int width, int height, int quietZone)
        {
            ByteMatrix input = code.Matrix;

            if (input == null)
            {
                throw new InvalidOperationException();
            }
            int inputWidth   = input.Width;
            int inputHeight  = input.Height;
            int qrWidth      = inputWidth + (quietZone << 1);
            int qrHeight     = inputHeight + (quietZone << 1);
            int outputWidth  = Math.Max(width, qrWidth);
            int outputHeight = Math.Max(height, qrHeight);

            int multiple = Math.Min(outputWidth / qrWidth, outputHeight / qrHeight);
            // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
            // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
            // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
            // handle all the padding from 100x100 (the actual QR) up to 200x160.
            int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
            int topPadding  = (outputHeight - (inputHeight * multiple)) / 2;

            BitMatrix output = new BitMatrix(outputWidth, outputHeight);

            for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple)
            {
                // Write the contents of this row of the barcode
                for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple)
                {
                    if (input.get(inputX, inputY) == 1)
                    {
                        output.setRegion(outputX, outputY, multiple, multiple);
                    }
                }
            }

            return(output);
        }
示例#27
0
        public static Bitmap Create(string content, Image centralImage)
        {
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            Hashtable         hashtables        = new Hashtable()
            {
                { EncodeHintType.CHARACTER_SET, "UTF-8" },
                { EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H }
            };
            ByteMatrix byteMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300, hashtables);
            Bitmap     bitmap     = byteMatrix.ToBitmap();
            Image      image      = centralImage;
            Size       encodeSize = multiFormatWriter.GetEncodeSize(content, BarcodeFormat.QR_CODE, 300, 300);
            int        num        = Math.Min((int)(encodeSize.Width / 3.5), image.Width);
            int        num1       = Math.Min((int)(encodeSize.Height / 3.5), image.Height);
            int        width      = (bitmap.Width - num) / 2;
            int        height     = (bitmap.Height - num1) / 2;
            Bitmap     bitmap1    = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb);
            Graphics   graphic    = Graphics.FromImage(bitmap1);

            try
            {
                graphic.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                graphic.SmoothingMode      = SmoothingMode.HighQuality;
                graphic.CompositingQuality = CompositingQuality.HighQuality;
                graphic.DrawImage(bitmap, 0, 0);
            }
            finally
            {
                if (graphic != null)
                {
                    graphic.Dispose();
                }
            }
            Graphics graphic1 = Graphics.FromImage(bitmap1);

            graphic1.FillRectangle(Brushes.White, width, height, num, num1);
            graphic1.DrawImage(image, width, height, num, num1);
            return(bitmap1);
        }
示例#28
0
        /// <summary>
        /// Convert the ByteMatrix to BitMatrix.
        /// </summary>
        /// <param name="matrix">The input matrix.</param>
        /// <returns>The output matrix.</returns>
        private static BitMatrix convertByteMatrixToBitMatrix(ByteMatrix matrix)
        {
            int matrixWidgth = matrix.Width;
            int matrixHeight = matrix.Height;

            var output = new BitMatrix(matrixWidgth, matrixHeight);

            output.clear();
            for (int i = 0; i < matrixWidgth; i++)
            {
                for (int j = 0; j < matrixHeight; j++)
                {
                    // Zero is white in the bytematrix
                    if (matrix[i, j] == 1)
                    {
                        output[i, j] = true;
                    }
                }
            }

            return(output);
        }
示例#29
0
 public void testApplyMaskPenaltyRule2()
 {
     {
         ByteMatrix matrix = new ByteMatrix(1, 1);
         matrix.set(0, 0, 0);
         Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule2(matrix));
     }
     {
         ByteMatrix matrix = new ByteMatrix(2, 2);
         matrix.set(0, 0, 0);
         matrix.set(1, 0, 0);
         matrix.set(0, 1, 0);
         matrix.set(1, 1, 1);
         Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule2(matrix));
     }
     {
         ByteMatrix matrix = new ByteMatrix(2, 2);
         matrix.set(0, 0, 0);
         matrix.set(1, 0, 0);
         matrix.set(0, 1, 0);
         matrix.set(1, 1, 0);
         Assert.AreEqual(3, MaskUtil.applyMaskPenaltyRule2(matrix));
     }
     {
         ByteMatrix matrix = new ByteMatrix(3, 3);
         matrix.set(0, 0, 0);
         matrix.set(1, 0, 0);
         matrix.set(2, 0, 0);
         matrix.set(0, 1, 0);
         matrix.set(1, 1, 0);
         matrix.set(2, 1, 0);
         matrix.set(0, 2, 0);
         matrix.set(1, 2, 0);
         matrix.set(2, 2, 0);
         // Four instances of 2x2 blocks.
         Assert.AreEqual(3 * 4, MaskUtil.applyMaskPenaltyRule2(matrix));
     }
 }
示例#30
0
        private void btnBarCode_Click(object sender, EventArgs e)
        {
            labShow.Text = "";
            string content = txtMsg.Text.Trim();
            Regex  regex   = new Regex("^[0-9]{13}$");

            if (!regex.IsMatch(content))
            {
                MessageBox.Show("请输入13位的数字!");
                return;
            }

            try
            {
                MultiFormatWriter writer = new MultiFormatWriter();
                ByteMatrix        matrix = writer.encode(content, BarcodeFormat.EAN_13, 360, 150);
                Bitmap            bitmap = matrix.ToBitmap();
                pictureBox1.Image = bitmap;


                //自动保存图片到当前目录
                SaveFileDialog save = new SaveFileDialog();
                save.Title            = "保存文件";
                save.Filter           = "图片文件|*.jpg;*.png;*.bmp|所有文件|*.*";
                save.RestoreDirectory = true;
                save.InitialDirectory = Application.StartupPath;
                if (save.ShowDialog() == DialogResult.OK)
                {
                    string filename = save.FileName;
                    bitmap.Save(filename);
                    labShow.Text = "图片已保存到:" + filename;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 private void txtBarcodeInput_TextChanged(object sender, TextChangedEventArgs e)
 {
     if (this.txtBarcodeInput.Text.Length == 13 && barcodeControl != null)
     {
         MultiFormatWriter barcodeWriter = new MultiFormatWriter();
         Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Send, new Action(delegate
         {
             _Global_C_ShowWaitingScreen();
             ByteMatrix barcodeData = barcodeWriter.encode(txtBarcodeInput.Text, BarcodeFormat.EAN_13, (int)(barcodeControl.imgBarcodeImg.Width), (int)(barcodeControl.imgBarcodeImg.Height * 0.8));
             barcodeControl.imgBarcodeImg.Source = getImageSource(barcodeData.ToBitmap());
         }));
         _Barcode_D_Dispose(txtBarcodeInput.Text);
     }
     else if (this.txtBarcodeInput.Text.Length == 16 && membershipControl != null)
     {
         MultiFormatWriter barcodeWriter = new MultiFormatWriter();
         Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Send, new Action(delegate
         {
             _Global_C_ShowWaitingScreen();
         }));
         _Membership_D_Dispose(txtBarcodeInput.Text);
     }
 }
        private unsafe Bitmap ConvertByteMatrixToImage(ByteMatrix bm)
        {
            Bitmap image = CreateGrayscaleImage(bm.Width, bm.Height);
            BitmapData sourceData;

            sourceData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
            int width = sourceData.Width;
            int height = sourceData.Height;
            int srcOffset = sourceData.Stride - width;
            byte* src = (byte*)sourceData.Scan0.ToPointer();
            for (int y = 0; y < height; y++)
            {
                // for each pixel
                for (int x = 0; x < width; x++, src++)
                {
                    *src = (byte)bm.Array[y][x];
                }
                src += srcOffset;
            }

            image.UnlockBits(sourceData);
            return image;
        }
示例#33
0
        // Apply mask penalty rule 3 and return the penalty. Find consecutive cells of 00001011101 or
        // 10111010000, and give penalty to them.  If we find patterns like 000010111010000, we give
        // penalties twice (i.e. 40 * 2).
        internal static int applyMaskPenaltyRule3(ByteMatrix matrix)
        {
            int penalty = 0;
            int width   = matrix.Width;
            int height  = matrix.Height;

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    // Tried to simplify following conditions but failed.
                    if (x + 6 < width && matrix[x, y] == 1 && matrix[x + 1, y] == 0 && matrix[x + 2, y] == 1 && matrix[x + 3, y] == 1 && matrix[x + 4, y] == 1 && matrix[x + 5, y] == 0 && matrix[x + 6, y] == 1 && ((x + 10 < width && matrix[x + 7, y] == 0 && matrix[x + 8, y] == 0 && matrix[x + 9, y] == 0 && matrix[x + 10, y] == 0) || (x - 4 >= 0 && matrix[x - 1, y] == 0 && matrix[x - 2, y] == 0 && matrix[x - 3, y] == 0 && matrix[x - 4, y] == 0)))
                    {
                        penalty += 40;
                    }
                    if (y + 6 < height && matrix[x, y] == 1 && matrix[x, y + 1] == 0 && matrix[x, y + 2] == 1 && matrix[x, y + 3] == 1 && matrix[x, y + 4] == 1 && matrix[x, y + 5] == 0 && matrix[x, y + 6] == 1 && ((y + 10 < height && matrix[x, y + 7] == 0 && matrix[x, y + 8] == 0 && matrix[x, y + 9] == 0 && matrix[x, y + 10] == 0) || (y - 4 >= 0 && matrix[x, y - 1] == 0 && matrix[x, y - 2] == 0 && matrix[x, y - 3] == 0 && matrix[x, y - 4] == 0)))
                    {
                        penalty += 40;
                    }
                }
            }
            return(penalty);
        }
示例#34
0
        // Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give
        // penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance. Examples:
        // -   0% => 100
        // -  40% =>  20
        // -  45% =>  10
        // -  50% =>   0
        // -  55% =>  10
        // -  55% =>  20
        // - 100% => 100
        public static int applyMaskPenaltyRule4(ByteMatrix matrix)
        {
            int numDarkCells = 0;

            sbyte[][] array  = matrix.getArray();
            int       width  = matrix.width();
            int       height = matrix.height();

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    if (array[y][x] == 1)
                    {
                        numDarkCells += 1;
                    }
                }
            }
            int    numTotalCells = matrix.height() * matrix.width();
            double darkRatio     = (double)numDarkCells / numTotalCells;

            return(Math.Abs((int)(darkRatio * 100 - 50)) / 5 * 10);
        }
示例#35
0
        static void Main(string[] args)
        {
            var        b  = BarcodeFormat.QrCode;
            var        g  = Guid.NewGuid().ToString();
            string     t  = "data=" + g;
            ByteMatrix bt = barcodeWriter.Encode(t, b, 150, 150);
            Image      i  = ConvertByteMatrixToImage(bt);

            i.Save(".\\" + g + ".png", ImageFormat.Png);

            Bitmap bitmap = new Bitmap(i);

            Result                   rawResult;
            RGBLuminanceSource       r       = new RGBLuminanceSource(bitmap, 150, 150);
            GlobalHistogramBinarizer x       = new GlobalHistogramBinarizer(r);
            BinaryBitmap             bitmap2 = new BinaryBitmap(x);
            var hints = new System.Collections.Hashtable();
            //hints.Add(DecodeHintType.PossibleFormats, BarcodeFormat.QrCode);
            int count = 0;
            {
                try
                {
                    rawResult = barcodeReader.Decode(bitmap2, hints);
                    if (rawResult != null)
                    {
                        count++;
                        var y = rawResult.Text;
                        var z = rawResult.BarcodeFormat.ToString();
                    }
                }
                catch (ReaderException e)
                {
                    return;
                }
            }
        }
示例#36
0
    public Sprite CreateQRCode(string context, Texture2D gameLogo = null, int offsetX = 0, int offsetY = 0)
    {
        QRCodeWriter qrwriter = new QRCodeWriter();
        Hashtable    table    = new Hashtable();

        table[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.Q;
        ByteMatrix matrix = qrwriter.encode(context, com.google.zxing.BarcodeFormat.QR_CODE, 440, 440, table);

        Texture2D pic        = new Texture2D(440, 440, TextureFormat.RGBA32, false);
        Color     whitecolor = new Color(238 / 255f, 245 / 255f, 212 / 255f);

        for (int x = 0; x < 440; x++)
        {
            for (int y = 0; y < 440; y++)
            {
                pic.SetPixel(x, y, matrix.get_Renamed(y, x) == 0 ? Color.black : whitecolor);
            }
        }

        if (gameLogo != null)
        {
            for (int x = 0; x < gameLogo.width; x++)
            {
                for (int y = 0; y < gameLogo.height; y++)
                {
                    pic.SetPixel(x + offsetX, y + offsetY, gameLogo.GetPixel(x, y));
                }
            }
        }

        pic.Apply(false);

        Sprite sp = Sprite.Create(pic, new Rect(0, 0, pic.width, pic.height), new Vector2(0.5f, 0.5f));

        return(sp);
    }
示例#37
0
        private unsafe Bitmap ConvertByteMatrixToImage(ByteMatrix bm)
        {
            Bitmap     image = CreateGrayscaleImage(bm.Width, bm.Height);
            BitmapData sourceData;

            sourceData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
            int   width     = sourceData.Width;
            int   height    = sourceData.Height;
            int   srcOffset = sourceData.Stride - width;
            byte *src       = (byte *)sourceData.Scan0.ToPointer();

            for (int y = 0; y < height; y++)
            {
                // for each pixel
                for (int x = 0; x < width; x++, src++)
                {
                    *src = (byte)bm.Array[y][x];
                }
                src += srcOffset;
            }

            image.UnlockBits(sourceData);
            return(image);
        }
        private void GenQR(string ssconfig)
        {
            string     qrText    = ssconfig;
            QRCode     code      = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
            ByteMatrix m         = code.Matrix;
            int        blockSize = Math.Max(pictureBox1.Height / m.Height, 1);

            var qrWidth  = m.Width * blockSize;
            var qrHeight = m.Height * blockSize;
            var dWidth   = pictureBox1.Width - qrWidth;
            var dHeight  = pictureBox1.Height - qrHeight;
            var maxD     = Math.Max(dWidth, dHeight);

            pictureBox1.SizeMode = maxD >= 7 * blockSize ? PictureBoxSizeMode.Zoom : PictureBoxSizeMode.CenterImage;

            Bitmap drawArea = new Bitmap((m.Width * blockSize), (m.Height * blockSize));

            using (Graphics g = Graphics.FromImage(drawArea))
            {
                g.Clear(Color.White);
                using (Brush b = new SolidBrush(Color.Black))
                {
                    for (int row = 0; row < m.Width; row++)
                    {
                        for (int col = 0; col < m.Height; col++)
                        {
                            if (m[row, col] != 0)
                            {
                                g.FillRectangle(b, blockSize * row, blockSize * col, blockSize, blockSize);
                            }
                        }
                    }
                }
            }
            pictureBox1.Image = drawArea;
        }
示例#39
0
 public void testApplyMaskPenaltyRule3()
 {
    {
       // Horizontal 00001011101.
       ByteMatrix matrix = new ByteMatrix(11, 1);
       matrix.set(0, 0, 0);
       matrix.set(1, 0, 0);
       matrix.set(2, 0, 0);
       matrix.set(3, 0, 0);
       matrix.set(4, 0, 1);
       matrix.set(5, 0, 0);
       matrix.set(6, 0, 1);
       matrix.set(7, 0, 1);
       matrix.set(8, 0, 1);
       matrix.set(9, 0, 0);
       matrix.set(10, 0, 1);
       Assert.AreEqual(40, MaskUtil.applyMaskPenaltyRule3(matrix));
    }
    {
       // Horizontal 10111010000.
       ByteMatrix matrix = new ByteMatrix(11, 1);
       matrix.set(0, 0, 1);
       matrix.set(1, 0, 0);
       matrix.set(2, 0, 1);
       matrix.set(3, 0, 1);
       matrix.set(4, 0, 1);
       matrix.set(5, 0, 0);
       matrix.set(6, 0, 1);
       matrix.set(7, 0, 0);
       matrix.set(8, 0, 0);
       matrix.set(9, 0, 0);
       matrix.set(10, 0, 0);
       Assert.AreEqual(40, MaskUtil.applyMaskPenaltyRule3(matrix));
    }
    {
       // Vertical 00001011101.
       ByteMatrix matrix = new ByteMatrix(1, 11);
       matrix.set(0, 0, 0);
       matrix.set(0, 1, 0);
       matrix.set(0, 2, 0);
       matrix.set(0, 3, 0);
       matrix.set(0, 4, 1);
       matrix.set(0, 5, 0);
       matrix.set(0, 6, 1);
       matrix.set(0, 7, 1);
       matrix.set(0, 8, 1);
       matrix.set(0, 9, 0);
       matrix.set(0, 10, 1);
       Assert.AreEqual(40, MaskUtil.applyMaskPenaltyRule3(matrix));
    }
    {
       // Vertical 10111010000.
       ByteMatrix matrix = new ByteMatrix(1, 11);
       matrix.set(0, 0, 1);
       matrix.set(0, 1, 0);
       matrix.set(0, 2, 1);
       matrix.set(0, 3, 1);
       matrix.set(0, 4, 1);
       matrix.set(0, 5, 0);
       matrix.set(0, 6, 1);
       matrix.set(0, 7, 0);
       matrix.set(0, 8, 0);
       matrix.set(0, 9, 0);
       matrix.set(0, 10, 0);
       Assert.AreEqual(40, MaskUtil.applyMaskPenaltyRule3(matrix));
    }
 }
示例#40
0
      /// <summary>
      /// Embed "dataBits" using "getMaskPattern". On success, modify the matrix and return true.
      /// For debugging purposes, it skips masking process if "getMaskPattern" is -1.
      /// See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.
      /// </summary>
      /// <param name="dataBits">The data bits.</param>
      /// <param name="maskPattern">The mask pattern.</param>
      /// <param name="matrix">The matrix.</param>
      public static void embedDataBits(BitArray dataBits, int maskPattern, ByteMatrix matrix)
      {
         int bitIndex = 0;
         int direction = -1;
         // Start from the right bottom cell.
         int x = matrix.Width - 1;
         int y = matrix.Height - 1;
         while (x > 0)
         {
            // Skip the vertical timing pattern.
            if (x == 6)
            {
               x -= 1;
            }
            while (y >= 0 && y < matrix.Height)
            {
               for (int i = 0; i < 2; ++i)
               {
                  int xx = x - i;
                  // Skip the cell if it's not empty.
                  if (!isEmpty(matrix[xx, y]))
                  {
                     continue;
                  }
                  int bit;
                  if (bitIndex < dataBits.Size)
                  {
                     bit = dataBits[bitIndex] ? 1 : 0;
                     ++bitIndex;
                  }
                  else
                  {
                     // Padding bit. If there is no bit left, we'll fill the left cells with 0, as described
                     // in 8.4.9 of JISX0510:2004 (p. 24).
                     bit = 0;
                  }

                  // Skip masking if mask_pattern is -1.
                  if (maskPattern != -1)
                  {
                     if (MaskUtil.getDataMaskBit(maskPattern, xx, y))
                     {
                        bit ^= 0x1;
                     }
                  }
                  matrix[xx, y] = bit;
               }
               y += direction;
            }
            direction = -direction; // Reverse the direction.
            y += direction;
            x -= 2; // Move to the left.
         }
         // All bits should be consumed.
         if (bitIndex != dataBits.Size)
         {
            throw new WriterException("Not all bits consumed: " + bitIndex + '/' + dataBits.Size);
         }
      }
示例#41
0
 // Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and
 // give penalty to them. Example: 00000 or 11111.
 internal static int applyMaskPenaltyRule1(ByteMatrix matrix)
 {
     return(applyMaskPenaltyRule1Internal(matrix, true) + applyMaskPenaltyRule1Internal(matrix, false));
 }
示例#42
0
 /// <summary>
 /// Apply mask penalty rule 3 and return the penalty. Find consecutive cells of 00001011101 or
 /// 10111010000, and give penalty to them.  If we find patterns like 000010111010000, we give
 /// penalties twice (i.e. 40 * 2).
 /// </summary>
 internal static int applyMaskPenaltyRule3(ByteMatrix matrix)
 {
     int penalty = 0;
     sbyte[][] array = matrix.Array;
     int width = matrix.Width;
     int height = matrix.Height;
     for (int y = 0; y < height; y++)
     {
       for (int x = 0; x < width; x++)
       {
     // Tried to simplify following conditions but failed.
     if (x + 6 < width && array[y][x] == 1 && array[y][x + 1] == 0 && array[y][x + 2] == 1 && array[y][x + 3] == 1 && array[y][x + 4] == 1 && array[y][x + 5] == 0 && array[y][x + 6] == 1 && ((x + 10 < width && array[y][x + 7] == 0 && array[y][x + 8] == 0 && array[y][x + 9] == 0 && array[y][x + 10] == 0) || (x - 4 >= 0 && array[y][x - 1] == 0 && array[y][x - 2] == 0 && array[y][x - 3] == 0 && array[y][x - 4] == 0)))
     {
       penalty += N3;
     }
     if (y + 6 < height && array[y][x] == 1 && array[y + 1][x] == 0 && array[y + 2][x] == 1 && array[y + 3][x] == 1 && array[y + 4][x] == 1 && array[y + 5][x] == 0 && array[y + 6][x] == 1 && ((y + 10 < height && array[y + 7][x] == 0 && array[y + 8][x] == 0 && array[y + 9][x] == 0 && array[y + 10][x] == 0) || (y - 4 >= 0 && array[y - 1][x] == 0 && array[y - 2][x] == 0 && array[y - 3][x] == 0 && array[y - 4][x] == 0)))
     {
       penalty += N3;
     }
       }
     }
     return penalty;
 }
示例#43
0
 private static void embedTimingPatterns(ByteMatrix matrix)
 {
    // -8 is for skipping position detection patterns (size 7), and two horizontal/vertical
    // separation patterns (size 1). Thus, 8 = 7 + 1.
    for (int i = 8; i < matrix.Width - 8; ++i)
    {
       int bit = (i + 1) % 2;
       // Horizontal line.
       if (isEmpty(matrix[i, 6]))
       {
          matrix[i, 6] = bit;
       }
       // Vertical line.
       if (isEmpty(matrix[6, i]))
       {
          matrix[6, i] = bit;
       }
    }
 }
示例#44
0
 /// <summary>
 /// Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and
 /// give penalty to them. Example: 00000 or 11111.
 /// </summary>
 internal static int applyMaskPenaltyRule1(ByteMatrix matrix)
 {
     return applyMaskPenaltyRule1Internal(matrix, true) + applyMaskPenaltyRule1Internal(matrix, false);
 }
示例#45
0
 private static void embedPositionDetectionPattern(int xStart, int yStart, ByteMatrix matrix)
 {
    for (int y = 0; y < 7; ++y)
    {
       for (int x = 0; x < 7; ++x)
       {
          matrix[xStart + x, yStart + y] = POSITION_DETECTION_PATTERN[y][x];
       }
    }
 }
示例#46
0
 /// <summary>
 /// Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give
 /// penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance.
 /// </summary>
 internal static int applyMaskPenaltyRule4(ByteMatrix matrix)
 {
     int numDarkCells = 0;
     sbyte[][] array = matrix.Array;
     int width = matrix.Width;
     int height = matrix.Height;
     for (int y = 0; y < height; y++)
     {
       sbyte[] arrayY = array[y];
       for (int x = 0; x < width; x++)
       {
     if (arrayY[x] == 1)
     {
       numDarkCells++;
     }
       }
     }
     int numTotalCells = matrix.Height * matrix.Width;
     double darkRatio = (double) numDarkCells / numTotalCells;
     int fivePercentVariances = (int)(Math.Abs(darkRatio - 0.5) * 20.0); // * 100.0 / 5.0
     return fivePercentVariances * N4;
 }
示例#47
0
 /// <summary>
 /// Embed the lonely dark dot at left bottom corner. JISX0510:2004 (p.46)
 /// </summary>
 /// <param name="matrix">The matrix.</param>
 private static void embedDarkDotAtLeftBottomCorner(ByteMatrix matrix)
 {
    if (matrix[8, matrix.Height - 8] == 0)
    {
       throw new WriterException();
    }
    matrix[8, matrix.Height - 8] = 1;
 }
示例#48
0
		private void ZXEncode(string content, int option)
		{
			System.String encoding = QRCodeConstantVariable.DefaultEncoding;
			ErrorCorrectionLevelInternal m_EcLevelInternal = ErrorCorrectionLevelInternal.H;
			QRCodeInternal qrCodeInternal = new QRCodeInternal();
			
			// Step 1: Choose the mode (encoding).
			Mode mode = EncoderInternal.chooseMode(content, encoding);
			
			// Step 2: Append "bytes" into "dataBits" in appropriate encoding.
			BitVector dataBits = new BitVector();
			EncoderInternal.appendBytes(content, mode, dataBits, encoding);
			// Step 3: Initialize QR code that can contain "dataBits".
			int numInputBytes = dataBits.sizeInBytes();
			EncoderInternal.initQRCode(numInputBytes, m_EcLevelInternal, mode, qrCodeInternal);
			
			// Step 4: Build another bit vector that contains header and data.
			BitVector headerAndDataBits = new BitVector();
			
			// Step 4.5: Append ECI message if applicable
			if (mode == Mode.BYTE && !QRCodeConstantVariable.DefaultEncoding.Equals(encoding))
			{
				CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
				if (eci != null)
				{
					EncoderInternal.appendECI(eci, headerAndDataBits);
				}
			}
			
			EncoderInternal.appendModeInfo(mode, headerAndDataBits);
			
			int numLetters = mode.Equals(Mode.BYTE)?dataBits.sizeInBytes():content.Length;
			EncoderInternal.appendLengthInfo(numLetters, qrCodeInternal.Version, mode, headerAndDataBits);
			headerAndDataBits.appendBitVector(dataBits);
			
			// Step 5: Terminate the bits properly.
			EncoderInternal.terminateBits(qrCodeInternal.NumDataBytes, headerAndDataBits);
			
			// Step 6: Interleave data bits with error correction code.
			BitVector finalBits = new BitVector();
			EncoderInternal.interleaveWithECBytes(headerAndDataBits, qrCodeInternal.NumTotalBytes, qrCodeInternal.NumDataBytes, qrCodeInternal.NumRSBlocks, finalBits);
			
			if(option == 3)
			{
				return;
			}
			
			// Step 7: Choose the mask pattern and set to "QRCodeInternal".
			ByteMatrix matrix = new ByteMatrix(qrCodeInternal.MatrixWidth, qrCodeInternal.MatrixWidth);
			qrCodeInternal.MaskPattern = EncoderInternal.chooseMaskPattern(finalBits, qrCodeInternal.EcLevelInternal, qrCodeInternal.Version, matrix);
			
			// Step 8.  Build the matrix and set it to "QRCodeInternal".
			MatrixUtil.buildMatrix(finalBits, qrCodeInternal.EcLevelInternal, qrCodeInternal.Version, qrCodeInternal.MaskPattern, matrix);
			qrCodeInternal.Matrix = matrix;
			
		}
示例#49
0
 private static void embedHorizontalSeparationPattern(int xStart, int yStart, ByteMatrix matrix)
 {
    for (int x = 0; x < 8; ++x)
    {
       if (!isEmpty(matrix[xStart + x, yStart]))
       {
          throw new WriterException();
       }
       matrix[xStart + x, yStart] = 0;
    }
 }
示例#50
0
 private static void embedVerticalSeparationPattern(int xStart, int yStart, ByteMatrix matrix)
 {
    for (int y = 0; y < 7; ++y)
    {
       if (!isEmpty(matrix[xStart, yStart + y]))
       {
          throw new WriterException();
       }
       matrix[xStart, yStart + y] = 0;
    }
 }
示例#51
0
 /// <summary>
 /// Embed position adjustment patterns if need be.
 /// </summary>
 /// <param name="version">The version.</param>
 /// <param name="matrix">The matrix.</param>
 private static void maybeEmbedPositionAdjustmentPatterns(Version version, ByteMatrix matrix)
 {
    if (version.VersionNumber < 2)
    {
       // The patterns appear if version >= 2
       return;
    }
    int index = version.VersionNumber - 1;
    int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index];
    int numCoordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index].Length;
    for (int i = 0; i < numCoordinates; ++i)
    {
       for (int j = 0; j < numCoordinates; ++j)
       {
          int y = coordinates[i];
          int x = coordinates[j];
          if (x == -1 || y == -1)
          {
             continue;
          }
          // If the cell is unset, we embed the position adjustment pattern here.
          if (isEmpty(matrix[x, y]))
          {
             // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
             // left top corner.
             embedPositionAdjustmentPattern(x - 2, y - 2, matrix);
          }
       }
    }
 }
示例#52
0
 /// <summary>
 /// Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both
 /// vertical and horizontal orders respectively.
 /// </summary>
 private static int applyMaskPenaltyRule1Internal(ByteMatrix matrix, bool isHorizontal)
 {
     int penalty = 0;
     int iLimit = isHorizontal ? matrix.Height : matrix.Width;
     int jLimit = isHorizontal ? matrix.Width : matrix.Height;
     sbyte[][] array = matrix.Array;
     for (int i = 0; i < iLimit; i++)
     {
       int numSameBitCells = 0;
       int prevBit = -1;
       for (int j = 0; j < jLimit; j++)
       {
     int bit = isHorizontal ? array[i][j] : array[j][i];
     if (bit == prevBit)
     {
       numSameBitCells++;
     }
     else
     {
       if (numSameBitCells >= 5)
       {
         penalty += N1 + (numSameBitCells - 5);
       }
       numSameBitCells = 1; // Include the cell itself.
       prevBit = bit;
     }
       }
       if (numSameBitCells > 5)
       {
     penalty += N1 + (numSameBitCells - 5);
       }
     }
     return penalty;
 }
示例#53
0
      /// <summary>
      /// Embed position detection patterns and surrounding vertical/horizontal separators.
      /// </summary>
      /// <param name="matrix">The matrix.</param>
      private static void embedPositionDetectionPatternsAndSeparators(ByteMatrix matrix)
      {
         // Embed three big squares at corners.
         int pdpWidth = POSITION_DETECTION_PATTERN[0].Length;
         // Left top corner.
         embedPositionDetectionPattern(0, 0, matrix);
         // Right top corner.
         embedPositionDetectionPattern(matrix.Width - pdpWidth, 0, matrix);
         // Left bottom corner.
         embedPositionDetectionPattern(0, matrix.Width - pdpWidth, matrix);

         // Embed horizontal separation patterns around the squares.
         const int hspWidth = 8;
         // Left top corner.
         embedHorizontalSeparationPattern(0, hspWidth - 1, matrix);
         // Right top corner.
         embedHorizontalSeparationPattern(matrix.Width - hspWidth, hspWidth - 1, matrix);
         // Left bottom corner.
         embedHorizontalSeparationPattern(0, matrix.Width - hspWidth, matrix);

         // Embed vertical separation patterns around the squares.
         const int vspSize = 7;
         // Left top corner.
         embedVerticalSeparationPattern(vspSize, 0, matrix);
         // Right top corner.
         embedVerticalSeparationPattern(matrix.Height - vspSize - 1, 0, matrix);
         // Left bottom corner.
         embedVerticalSeparationPattern(vspSize, matrix.Height - vspSize, matrix);
      }
示例#54
0
 /// <summary>
 /// Note that we cannot unify the function with embedPositionDetectionPattern() despite they are
 /// almost identical, since we cannot write a function that takes 2D arrays in different sizes in
 /// C/C++. We should live with the fact.
 /// </summary>
 /// <param name="xStart">The x start.</param>
 /// <param name="yStart">The y start.</param>
 /// <param name="matrix">The matrix.</param>
 private static void embedPositionAdjustmentPattern(int xStart, int yStart, ByteMatrix matrix)
 {
    for (int y = 0; y < 5; ++y)
    {
       for (int x = 0; x < 5; ++x)
       {
          matrix[xStart + x, yStart + y] = POSITION_ADJUSTMENT_PATTERN[y][x];
       }
    }
 }
示例#55
0
 public void testApplyMaskPenaltyRule4()
 {
    {
       // Dark cell ratio = 0%
       ByteMatrix matrix = new ByteMatrix(1, 1);
       matrix.set(0, 0, 0);
       Assert.AreEqual(100, MaskUtil.applyMaskPenaltyRule4(matrix));
    }
    {
       // Dark cell ratio = 5%
       ByteMatrix matrix = new ByteMatrix(2, 1);
       matrix.set(0, 0, 0);
       matrix.set(0, 0, 1);
       Assert.AreEqual(0, MaskUtil.applyMaskPenaltyRule4(matrix));
    }
    {
       // Dark cell ratio = 66.67%
       ByteMatrix matrix = new ByteMatrix(6, 1);
       matrix.set(0, 0, 0);
       matrix.set(1, 0, 1);
       matrix.set(2, 0, 1);
       matrix.set(3, 0, 1);
       matrix.set(4, 0, 1);
       matrix.set(5, 0, 0);
       Assert.AreEqual(30, MaskUtil.applyMaskPenaltyRule4(matrix));
    }
 }
示例#56
0
      /// <summary>
      /// Embed basic patterns. On success, modify the matrix and return true.
      /// The basic patterns are:
      /// - Position detection patterns
      /// - Timing patterns
      /// - Dark dot at the left bottom corner
      /// - Position adjustment patterns, if need be
      /// </summary>
      /// <param name="version">The version.</param>
      /// <param name="matrix">The matrix.</param>
      public static void embedBasicPatterns(Version version, ByteMatrix matrix)
      {
         // Let's get started with embedding big squares at corners.
         embedPositionDetectionPatternsAndSeparators(matrix);
         // Then, embed the dark dot at the left bottom corner.
         embedDarkDotAtLeftBottomCorner(matrix);

         // Position adjustment patterns appear if version >= 2.
         maybeEmbedPositionAdjustmentPatterns(version, matrix);
         // Timing patterns should be embedded after position adj. patterns.
         embedTimingPatterns(matrix);
      }
示例#57
0
      private static int chooseMaskPattern(BitArray bits,
                                           ErrorCorrectionLevel ecLevel,
                                           Version version,
                                           ByteMatrix matrix)
      {
         int minPenalty = Int32.MaxValue;  // Lower penalty is better.
         int bestMaskPattern = -1;
         // We try all mask patterns to choose the best one.
         for (int maskPattern = 0; maskPattern < QRCode.NUM_MASK_PATTERNS; maskPattern++)
         {

            MatrixUtil.buildMatrix(bits, ecLevel, version, maskPattern, matrix);
            int penalty = calculateMaskPenalty(matrix);
            if (penalty < minPenalty)
            {

               minPenalty = penalty;
               bestMaskPattern = maskPattern;
            }
         }
         return bestMaskPattern;
      }
示例#58
0
      /// <summary>
      /// Embed type information. On success, modify the matrix.
      /// </summary>
      /// <param name="ecLevel">The ec level.</param>
      /// <param name="maskPattern">The mask pattern.</param>
      /// <param name="matrix">The matrix.</param>
      public static void embedTypeInfo(ErrorCorrectionLevel ecLevel, int maskPattern, ByteMatrix matrix)
      {
         BitArray typeInfoBits = new BitArray();
         makeTypeInfoBits(ecLevel, maskPattern, typeInfoBits);

         for (int i = 0; i < typeInfoBits.Size; ++i)
         {
            // Place bits in LSB to MSB order.  LSB (least significant bit) is the last value in
            // "typeInfoBits".
            int bit = typeInfoBits[typeInfoBits.Size - 1 - i] ? 1 : 0;

            // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).
            int x1 = TYPE_INFO_COORDINATES[i][0];
            int y1 = TYPE_INFO_COORDINATES[i][1];
            matrix[x1, y1] = bit;

            if (i < 8)
            {
               // Right top corner.
               int x2 = matrix.Width - i - 1;
               int y2 = 8;
               matrix[x2, y2] = bit;
            }
            else
            {
               // Left bottom corner.
               int x2 = 8;
               int y2 = matrix.Height - 7 + (i - 8);
               matrix[x2, y2] = bit;
            }
         }
      }
示例#59
0
      /// <summary>
      /// Encodes the specified content.
      /// </summary>
      /// <param name="content">The content.</param>
      /// <param name="ecLevel">The ec level.</param>
      /// <param name="hints">The hints.</param>
      /// <returns></returns>
      public static QRCode encode(String content,
                                ErrorCorrectionLevel ecLevel,
                                IDictionary<EncodeHintType, object> hints)
      {
         // Determine what character encoding has been specified by the caller, if any
#if !SILVERLIGHT || WINDOWS_PHONE
         String encoding = hints == null || !hints.ContainsKey(EncodeHintType.CHARACTER_SET) ? null : (String)hints[EncodeHintType.CHARACTER_SET];
         if (encoding == null)
         {
            encoding = DEFAULT_BYTE_MODE_ENCODING;
         }
         bool generateECI = !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding);
#else
         // Silverlight supports only UTF-8 and UTF-16 out-of-the-box
         const string encoding = "UTF-8";
         // caller of the method can only control if the ECI segment should be written
         // character set is fixed to UTF-8; but some scanners doesn't like the ECI segment
         bool generateECI = (hints != null && hints.ContainsKey(EncodeHintType.CHARACTER_SET));
#endif

         // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
         // multiple modes / segments even if that were more efficient. Twould be nice.
         Mode mode = chooseMode(content, encoding);

         // This will store the header information, like mode and
         // length, as well as "header" segments like an ECI segment.
         BitArray headerBits = new BitArray();

         // Append ECI segment if applicable
         if (mode == Mode.BYTE && generateECI)
         {
            CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
            if (eci != null)
            {
               var eciIsExplicitDisabled = (hints != null && hints.ContainsKey(EncodeHintType.DISABLE_ECI) ? (bool)hints[EncodeHintType.DISABLE_ECI] : false);
               if (!eciIsExplicitDisabled)
               {
                  appendECI(eci, headerBits);
               }
            }
         }

         // (With ECI in place,) Write the mode marker
         appendModeInfo(mode, headerBits);

         // Collect data within the main segment, separately, to count its size if needed. Don't add it to
         // main payload yet.
         BitArray dataBits = new BitArray();
         appendBytes(content, mode, dataBits, encoding);

         // Hard part: need to know version to know how many bits length takes. But need to know how many
         // bits it takes to know version. First we take a guess at version by assuming version will be
         // the minimum, 1:

         int provisionalBitsNeeded = headerBits.Size
             + mode.getCharacterCountBits(Version.getVersionForNumber(1))
             + dataBits.Size;
         Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);

         // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
         int bitsNeeded = headerBits.Size
             + mode.getCharacterCountBits(provisionalVersion)
             + dataBits.Size;
         Version version = chooseVersion(bitsNeeded, ecLevel);

         BitArray headerAndDataBits = new BitArray();
         headerAndDataBits.appendBitArray(headerBits);
         // Find "length" of main segment and write it
         int numLetters = mode == Mode.BYTE ? dataBits.SizeInBytes : content.Length;
         appendLengthInfo(numLetters, version, mode, headerAndDataBits);
         // Put data together into the overall payload
         headerAndDataBits.appendBitArray(dataBits);

         Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
         int numDataBytes = version.TotalCodewords - ecBlocks.TotalECCodewords;

         // Terminate the bits properly.
         terminateBits(numDataBytes, headerAndDataBits);

         // Interleave data bits with error correction code.
         BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
                                                    version.TotalCodewords,
                                                    numDataBytes,
                                                    ecBlocks.NumBlocks);

         QRCode qrCode = new QRCode
                            {
                               ECLevel = ecLevel, 
                               Mode = mode,
                               Version = version
                            };

         //  Choose the mask pattern and set to "qrCode".
         int dimension = version.DimensionForVersion;
         ByteMatrix matrix = new ByteMatrix(dimension, dimension);
         int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
         qrCode.MaskPattern = maskPattern;

         // Build the matrix and set it to "qrCode".
         MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
         qrCode.Matrix = matrix;

         return qrCode;
      }
示例#60
0
      /// <summary>
      /// Embed version information if need be. On success, modify the matrix and return true.
      /// See 8.10 of JISX0510:2004 (p.47) for how to embed version information.
      /// </summary>
      /// <param name="version">The version.</param>
      /// <param name="matrix">The matrix.</param>
      public static void maybeEmbedVersionInfo(Version version, ByteMatrix matrix)
      {
         if (version.VersionNumber < 7)
         {
            // Version info is necessary if version >= 7.
            return; // Don't need version info.
         }
         BitArray versionInfoBits = new BitArray();
         makeVersionInfoBits(version, versionInfoBits);

         int bitIndex = 6 * 3 - 1; // It will decrease from 17 to 0.
         for (int i = 0; i < 6; ++i)
         {
            for (int j = 0; j < 3; ++j)
            {
               // Place bits in LSB (least significant bit) to MSB order.
               var bit = versionInfoBits[bitIndex] ? 1 : 0;
               bitIndex--;
               // Left bottom corner.
               matrix[i, matrix.Height - 11 + j] = bit;
               // Right bottom corner.
               matrix[matrix.Height - 11 + j, i] = bit;
            }
         }
      }