예제 #1
0
        public static void writeToFile(COMMON.ByteMatrix matrix, System.Drawing.Imaging.ImageFormat format, string file)
        {
            System.Drawing.Imaging.EncoderParameters eps = new System.Drawing.Imaging.EncoderParameters();
            eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
            Bitmap bmap = toBitmap(matrix);

            bmap.Save(file, format);
        }
예제 #2
0
        public static Bitmap Encode_Code_39(string content)
        {
            Code39Writer ean8w      = new Code39Writer();
            ByteMatrix   byteMatrix = ean8w.encode(content, BarcodeFormat.CODE_39, 400, 38);
            Bitmap       bitmap     = ByteMatrixToBitmap(byteMatrix);

            return(bitmap);
        }
예제 #3
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).
 public static int applyMaskPenaltyRule3(ByteMatrix matrix)
 {
     int penalty = 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)
         {
             // 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 += 40;
             }
             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 += 40;
             }
         }
     }
     return penalty;
 }
예제 #4
0
 public QRCode()
 {
     mode = null;
     ecLevel = null;
     version = -1;
     matrixWidth = -1;
     maskPattern = -1;
     numTotalBytes = -1;
     numDataBytes = -1;
     numECBytes = -1;
     numRSBlocks = -1;
     matrix = null;
 }
예제 #5
0
 public Bitmap toBitmap(ByteMatrix matrix)
 {
     int width = matrix.Width;
     int height = matrix.Height;
     Bitmap bmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
     for (int x = 0; x < width; x++)
     {
         for (int y = 0; y < height; y++)
         {
             bmap.SetPixel(x, y, matrix.get_Renamed(x, y) != -1 ? ColorTranslator.FromHtml("0xFF000000") : ColorTranslator.FromHtml("0xFFFFFFFF"));
         }
     }
     return bmap;
 }
예제 #6
0
        public static Bitmap toBitmap(ByteMatrix matrix)
        {
            int    width  = matrix.Width;
            int    height = matrix.Height;
            Bitmap bmap   = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    bmap.SetPixel(x, y, matrix.get_Renamed(x, y) != -1 ? ColorTranslator.FromHtml("0xFF000000") : ColorTranslator.FromHtml("0xFFFFFFFF"));
                }
            }
            return(bmap);
        }
예제 #7
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;
 }
예제 #8
0
        private void CreateSquares(ByteMatrix byteMatrix, int squareSize)
        {
            squares = new Square[(byteMatrix.Width / squareSize) + 1, (byteMatrix.Height / squareSize) + 1];

            for (int y = 0, cntY = 0; y < byteMatrix.Height; y+=squareSize, cntY++)
            {
                for (int x = 0, cntX = 0; x < byteMatrix.Width; x+=squareSize, cntX++)
                {
                    Color clr;
                    if (byteMatrix.Array[x][y] == 0)
                        clr = Color.Black;
                    else
                        clr = Color.White;

                    squares[cntX, cntY] = new Square(
                        new Size(squareSize, squareSize),
                        new System.Drawing.Point(cntX * squareSize, cntY * squareSize)
                        );
                    squares[cntX, cntY].Color = clr;
                }
            }
        }
예제 #9
0
        // Encode "bytes" with the error correction level "getECLevel". The encoding mode will be chosen
        // internally by chooseMode(). On success, store the result in "qrCode" and return true.
        // We recommend you to use QRCode.EC_LEVEL_L (the lowest level) for
        // "getECLevel" since our primary use is to show QR code on desktop screens. We don't need very
        // strong error correction for this purpose.
        //
        // Note that there is no way to encode bytes in MODE_KANJI. We might want to add EncodeWithMode()
        // with which clients can specify the encoding mode. For now, we don't need the functionality.
        public static void encode(String content, ErrorCorrectionLevel ecLevel, QRCode qrCode)
        {
            // Step 1: Choose the mode (encoding).
            Mode mode = chooseMode(content);

            // Step 2: Append "bytes" into "dataBits" in appropriate encoding.
            BitVector dataBits = new BitVector();
            appendBytes(content, mode, dataBits);
            // Step 3: Initialize QR code that can contain "dataBits".
            int numInputBytes = dataBits.sizeInBytes();
            initQRCode(numInputBytes, ecLevel, mode, qrCode);

            // Step 4: Build another bit vector that contains header and data.
            BitVector headerAndDataBits = new BitVector();
            appendModeInfo(qrCode.getMode(), headerAndDataBits);
            appendLengthInfo(content.Length, qrCode.getVersion(), qrCode.getMode(), headerAndDataBits);
            headerAndDataBits.appendBitVector(dataBits);

            // Step 5: Terminate the bits properly.
            terminateBits(qrCode.getNumDataBytes(), headerAndDataBits);

            // Step 6: Interleave data bits with error correction code.
            BitVector finalBits = new BitVector();
            interleaveWithECBytes(headerAndDataBits, qrCode.getNumTotalBytes(), qrCode.getNumDataBytes(),
                qrCode.getNumRSBlocks(), finalBits);

            // Step 7: Choose the mask pattern and set to "qrCode".
            ByteMatrix matrix = new ByteMatrix(qrCode.getMatrixWidth(), qrCode.getMatrixWidth());
            qrCode.setMaskPattern(chooseMaskPattern(finalBits, qrCode.getECLevel(), qrCode.getVersion(),
                matrix));

            // Step 8.  Build the matrix and set it to "qrCode".
            MatrixUtil.buildMatrix(finalBits, qrCode.getECLevel(), qrCode.getVersion(),
                qrCode.getMaskPattern(), matrix);
            qrCode.setMatrix(matrix);
            // Step 9.  Make sure we have a valid QR Code.
            if (!qrCode.isValid()) {
              throw new WriterException("Invalid QR code: " + qrCode.toString());
            }
        }
예제 #10
0
 private static int chooseMaskPattern(BitVector bits, ErrorCorrectionLevel ecLevel, int version,ByteMatrix matrix)
 {
     try{
           int minPenalty = int.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;
       }catch(Exception e){
           throw new ReaderException(e.Message);
       }
 }
예제 #11
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)
 {
     int penalty = 0;
     penalty += MaskUtil.applyMaskPenaltyRule1(matrix);
     penalty += MaskUtil.applyMaskPenaltyRule2(matrix);
     penalty += MaskUtil.applyMaskPenaltyRule3(matrix);
     penalty += MaskUtil.applyMaskPenaltyRule4(matrix);
     return penalty;
 }
예제 #12
0
 // Embed position adjustment patterns if need be.
 private static void maybeEmbedPositionAdjustmentPatterns(int version, ByteMatrix matrix)
 {
     if (version < 2) {  // The patterns appear if version >= 2
       return;
     }
     int index = version - 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.get(y, x))) {
           // -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);
         }
       }
     }
 }
 /// <summary>
 /// What to do when the selection changes in the QR Code site list:
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void cmboExportSiteQR_SelectedIndexChanged(object sender, EventArgs e)
 {
     // Asbestos underpants:
     try
     {
         // Get the current selection of the combo box and make sure it
         // isn't empty:
         String site = (string)cmboExportSiteQR.Text;
         if (!String.IsNullOrEmpty(site))
         {
             // Ask the main form to give us the site parameters for this site.
             // Since the main form has all the code to do this, we'll ask it
             // to do the dirty work.
             SiteParameters siteParams = caller.GetSiteParamsForQRCode(site);
             // Now we'll generate the text we'll embed into the QR Code.  We want
             // this to be as compact as we can get it, so our "headings" will be
             // single letters.  We'll start off with an identifying header so the
             // QR Code reader will know the format of our string.  We delimite the
             // string with pipes, which aren't allowed in any of our fields.  We
             // want this to match as closely to the values of the XML export file
             // for consistency.  That means the hash engine and the character
             // limit fields will need some tweaking.
             StringBuilder sb = new StringBuilder();
             sb.Append("CRYPTNOSv1|" +
                 "S:" + siteParams.Site + "|" +
                 "H:" + HashEngine.HashEnumStringToDisplayHash(siteParams.Hash) + "|" +
                 "I:" + siteParams.Iterations.ToString() + "|" +
                 "C:" + siteParams.CharTypes.ToString() + "|L:");
             if (siteParams.CharLimit < 0) sb.Append("0");
             else sb.Append(siteParams.CharLimit.ToString());
             // Now that we've built our string, use the QRCodeWriter from ZXing to
             // build the QR Code image and assign the bitmap to the picture box:
             byteMatrix = qrCodeWriter.encode(sb.ToString(),
                 BarcodeFormat.QR_CODE, 200, 200);
             pictureBox1.Image = byteMatrix.ToBitmap();
         }
         // If the selection in the combo box wasn't useful, empty the picture box:
         else pictureBox1.Image = null;
     }
     // Similarly, if anything blew up, empty the picture box:
     catch { pictureBox1.Image = null; }
 }
예제 #14
0
        // 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.
        public static void embedDataBits(BitVector 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.get(y, xx))) {
                    continue;
                  }
                  int bit;
                  if (bitIndex < dataBits.size()) {
                    bit = dataBits.at(bitIndex);
                    ++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) {
                    int mask = MaskUtil.getDataMaskBit(maskPattern, xx, y);
                    bit ^= mask;
                  }
                  matrix.set(y, xx, 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());
            }
        }
예제 #15
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.
 public static int applyMaskPenaltyRule1(ByteMatrix matrix)
 {
     return applyMaskPenaltyRule1Internal(matrix, true) + applyMaskPenaltyRule1Internal(matrix, false);
 }
예제 #16
0
 private static void embedHorizontalSeparationPattern(int xStart, int yStart,ByteMatrix matrix)
 {
     // We know the width and height.
     if (HORIZONTAL_SEPARATION_PATTERN[0].Length != 8 || HORIZONTAL_SEPARATION_PATTERN.Length != 1) {
       throw new WriterException("Bad horizontal separation pattern");
     }
     for (int x = 0; x < 8; ++x) {
       if (!isEmpty(matrix.get(yStart, xStart + x))) {
         throw new WriterException();
       }
       matrix.set(yStart, xStart + x, HORIZONTAL_SEPARATION_PATTERN[0][x]);
     }
 }
예제 #17
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.get(yStart + y, xStart + x))) {
           throw new WriterException();
         }
         matrix.set(yStart + y, xStart + x, POSITION_ADJUSTMENT_PATTERN[y][x]);
       }
     }
 }
예제 #18
0
 // Embed the lonely dark dot at left bottom corner. JISX0510:2004 (p.46)
 private static void embedDarkDotAtLeftBottomCorner(ByteMatrix matrix)
 {
     if (matrix.get(matrix.height() - 8, 8) == 0) {
       throw new WriterException();
     }
     matrix.set(matrix.height() - 8, 8, 1);
 }
예제 #19
0
        // 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.
        public static void maybeEmbedVersionInfo(int version, ByteMatrix matrix)
        {
            if (version < 7) {  // Version info is necessary if version >= 7.
              return;  // Don't need version info.
            }
            BitVector versionInfoBits = new BitVector();
            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.
                int bit = versionInfoBits.at(bitIndex);
                bitIndex--;
                // Left bottom corner.
                matrix.set(matrix.height() - 11 + j, i, bit);
                // Right bottom corner.
                matrix.set(i, matrix.height() - 11 + j, bit);
              }
            }
        }
예제 #20
0
        // Embed type information. On success, modify the matrix.
        public static void embedTypeInfo(ErrorCorrectionLevel ecLevel, int maskPattern, ByteMatrix matrix)
        {
            BitVector typeInfoBits = new BitVector();
            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.at(typeInfoBits.size() - 1 - i);

              // 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.set(y1, x1, bit);

              if (i < 8) {
                // Right top corner.
                int x2 = matrix.width() - i - 1;
                int y2 = 8;
                matrix.set(y2, x2, bit);
              } else {
                // Left bottom corner.
                int x2 = 8;
                int y2 = matrix.height() - 7 + (i - 8);
                matrix.set(y2, x2, bit);
              }
            }
        }
예제 #21
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;
 }
예제 #22
0
 private int GetSizeOf1Square(ByteMatrix byteMatrix)
 {
     // The first line is compose initaly by seven black square
     int size = 0;
     // Try if it's a border (sound's like all pixel are white [-1])
     int row = 0;
     bool found = false;
     while (!found)
     {
         for (int x = 0; x < byteMatrix.Array[row].Length; x++)
         {
             if (byteMatrix.Array[row][x] == 0)
             {
                 found = true;
                 break;
             }
         }
         row++;
     }
     //while (byteMatrix.Array[row][size++] == -1) ;
     while (byteMatrix.Array[row][size++] == 0) ;
     return ((size - 1) / 7);
 }
예제 #23
0
 // Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both
 // vertical and horizontal orders respectively.
 private static int applyMaskPenaltyRule1Internal(ByteMatrix matrix, bool isHorizontal)
 {
     int penalty = 0;
     int numSameBitCells = 0;
     int prevBit = -1;
     // Horizontal mode:
     //   for (int i = 0; i < matrix.height(); ++i) {
     //     for (int j = 0; j < matrix.width(); ++j) {
     //       int bit = matrix.get(i, j);
     // Vertical mode:
     //   for (int i = 0; i < matrix.width(); ++i) {
     //     for (int j = 0; j < matrix.height(); ++j) {
     //       int bit = matrix.get(j, i);
     int iLimit = isHorizontal ? matrix.height() : matrix.width();
     int jLimit = isHorizontal ? matrix.width() : matrix.height();
     sbyte[][] array = matrix.getArray();
     for (int i = 0; i < iLimit; ++i)
     {
         for (int j = 0; j < jLimit; ++j)
         {
             int bit = isHorizontal ? array[i][j] : array[j][i];
             if (bit == prevBit)
             {
                 numSameBitCells += 1;
                 // Found five repetitive cells with the same color (bit).
                 // We'll give penalty of 3.
                 if (numSameBitCells == 5)
                 {
                     penalty += 3;
                 }
                 else if (numSameBitCells > 5)
                 {
                     // After five repetitive cells, we'll add the penalty one
                     // by one.
                     penalty += 1;
                 }
             }
             else
             {
                 numSameBitCells = 1;  // Include the cell itself.
                 prevBit = bit;
             }
         }
         numSameBitCells = 0;  // Clear at each row/column.
     }
     return penalty;
 }
예제 #24
0
 // Set all cells to -1.  -1 means that the cell is empty (not set yet).
 //
 // JAVAPORT: We shouldn't need to do this at all. The code should be rewritten to begin encoding
 // with the ByteMatrix initialized all to zero.
 public static void clearMatrix(ByteMatrix matrix)
 {
     matrix.clear((sbyte)(-1));
 }
예제 #25
0
        private ByteMatrix QRCodeGen(string text, int width, int height)
        {
            try
            {
                QRCodeWriter writer = new QRCodeWriter(0);
                Hashtable hints = new Hashtable();

                hints.Add(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.M);
                hints.Add("Version", "7");

                ByteMatrix _matrix = writer.encode(text, BarcodeFormat.QR_CODE, width, height, hints);

                #region Supress border white line
                int row = -1;
                int col = -1;
                int endRow = 0;
                int endCol = 0;
                bool isWhiteLine = true;

                while (isWhiteLine)
                {
                    row++;
                    for (int i = 0; i < _matrix.Width; i++)
                    {
                        if (_matrix.Array[row][i] == 0)
                        {
                            isWhiteLine = false;
                            break;
                        }
                    }
                }

                isWhiteLine = true;
                endRow = _matrix.Height;
                while (isWhiteLine)
                {
                    endRow--;
                    for (int i = 0; i < _matrix.Width; i++)
                    {
                        if (_matrix.Array[endRow][i] == 0)
                        {
                            isWhiteLine = false;
                            break;
                        }
                    }
                }

                isWhiteLine = true;
                while (isWhiteLine)
                {
                    col++;
                    for (int i = 0; i < _matrix.Height; i++)
                    {
                        if (_matrix.Array[i][col] == 0)
                        {
                            isWhiteLine = false;
                            break;
                        }
                    }
                }

                isWhiteLine = true;
                endCol = _matrix.Width;
                while (isWhiteLine)
                {
                    endCol--;
                    for (int i = 0; i < _matrix.Height; i++)
                    {
                        if (_matrix.Array[i][endCol] == 0)
                        {
                            isWhiteLine = false;
                            break;
                        }
                    }
                }

                #endregion

                ByteMatrix final = new ByteMatrix(endCol - col, endRow - row);
                for (int y = row; y < endRow; y++)
                {
                    for (int x = col; x < endCol; x++)
                    {
                        final.Array[x - col][y - row] = _matrix.Array[x][y];
                    }
                }

                return final;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
예제 #26
0
        // 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
        public static void embedBasicPatterns(int version, ByteMatrix matrix)
        {
            try
              {
                    // 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);
              }catch(Exception e){
                throw new WriterException (e.Message);
              }
        }
예제 #27
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.get(yStart + y, xStart + x))) {
           throw new WriterException();
         }
         matrix.set(yStart + y, xStart + x, POSITION_DETECTION_PATTERN[y][x]);
       }
     }
 }
예제 #28
0
 // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
 // success, store the result in "matrix" and return true.
 public static void buildMatrix(BitVector dataBits, ErrorCorrectionLevel ecLevel, int version,int maskPattern, ByteMatrix matrix)
 {
     try{
             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);
        }catch(Exception e){
             throw  new WriterException(e.Message);
        }
 }
예제 #29
0
        public static void writeToFile(ByteMatrix matrix, System.Drawing.Imaging.ImageFormat format, string file)
        {
            Bitmap bmap = toBitmap(matrix);

            bmap.Save(file, format);
        }
예제 #30
0
        // Embed position detection patterns and surrounding vertical/horizontal separators.
        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.
            int hspWidth = HORIZONTAL_SEPARATION_PATTERN[0].Length;
            // 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.
            int vspSize = VERTICAL_SEPARATION_PATTERN.Length;
            // 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);
        }
예제 #31
0
 // This takes ownership of the 2D array.
 public void setMatrix(ByteMatrix value)
 {
     matrix = value;
 }
예제 #32
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 (!isValidValue(matrix.get(6, i))) {
         throw new WriterException();
       }
       if (isEmpty(matrix.get(6, i))) {
         matrix.set(6, i, bit);
       }
       // Vertical line.
       if (!isValidValue(matrix.get(i, 6))) {
         throw new WriterException();
       }
       if (isEmpty(matrix.get(i, 6))) {
         matrix.set(i, 6, bit);
       }
     }
 }
예제 #33
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 ByteMatrix renderResult(QRCode code, int width, int height)
        {
            ByteMatrix input = code.getMatrix();
            int inputWidth = input.width();
            int inputHeight = input.height();
            int qrWidth = inputWidth + (QUIET_ZONE_SIZE << 1);
            int qrHeight = inputHeight + (QUIET_ZONE_SIZE << 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 accomodate 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;

            ByteMatrix output = new ByteMatrix(outputHeight, outputWidth);
            sbyte[][] outputArray = output.getArray();

            // We could be tricky and use the first row in each set of multiple as the temporary storage,
            // instead of allocating this separate array.
            sbyte[] row = new sbyte[outputWidth];

            // 1. Write the white lines at the top
            for (int y = 0; y < topPadding; y++) {
              setRowColor(outputArray[y], unchecked((sbyte)255));
            }

            // 2. Expand the QR image to the multiple
            sbyte[][] inputArray = input.getArray();
            for (int y = 0; y < inputHeight; y++) {
              // a. Write the white pixels at the left of each row
              for (int x = 0; x < leftPadding; x++) {
                row[x] = unchecked((sbyte) 255);
              }

              // b. Write the contents of this row of the barcode
              int offset = leftPadding;
              for (int x = 0; x < inputWidth; x++) {
                sbyte value = (inputArray[y][x] == 1) ? (sbyte) 0 : unchecked((sbyte) 255);
                for (int z = 0; z < multiple; z++) {
                  row[offset + z] = value;
                }
                offset += multiple;
              }

              // c. Write the white pixels at the right of each row
              offset = leftPadding + (inputWidth * multiple);
              for (int x = offset; x < outputWidth; x++) {
                row[x] = unchecked((sbyte) 255);
              }

              // d. Write the completed row multiple times
              offset = topPadding + (y * multiple);
              for (int z = 0; z < multiple; z++) {
                System.Array.Copy(row, 0, outputArray[offset + z], 0, outputWidth);
              }
            }

            // 3. Write the white lines at the bottom
            int offset2 = topPadding + (inputHeight * multiple);
            for (int y = offset2; y < outputHeight; y++)
            {
              setRowColor(outputArray[y], unchecked((sbyte) 255));
            }
            return output;
        }
예제 #34
0
 private static void embedVerticalSeparationPattern(int xStart, int yStart,ByteMatrix matrix)
 {
     // We know the width and height.
     if (VERTICAL_SEPARATION_PATTERN[0].Length != 1 || VERTICAL_SEPARATION_PATTERN.Length != 7) {
       throw new WriterException("Bad vertical separation pattern");
     }
     for (int y = 0; y < 7; ++y) {
       if (!isEmpty(matrix.get(yStart + y, xStart))) {
         throw new WriterException();
       }
       matrix.set(yStart + y, xStart, VERTICAL_SEPARATION_PATTERN[y][0]);
     }
 }