Ejemplo n.º 1
0
        /// <summary>
        /// Decode a QRCode
        /// </summary>
        /// <param name="img">image containing the QRCode</param>
        private QRCode(MyImage img)
        {
            // Copy image on this object
            image = new Pixel[img.image.GetLength(0), img.image.GetLength(1)];
            for (int i = 0; i < image.GetLength(0); i++)
            {
                for (int j = 0; j < image.GetLength(1); j++)
                {
                    image[i, j] = new Pixel(img.image[i, j]);
                }
            }
            /* https://www.researchgate.net/publication/221337868_Fast_QR_Code_Detection_in_Arbitrarily_Acquired_Images */
            //Assume image is flat on the surface
            //Find the size of a finder and the size of a code to determine the version
            //and the size of a bit to be accurate while reading
            // plus save the start index of QRCode;
            // Different size horizontal and vertical (if image is warped
            int  sizeOfFinderHorizontal = 0;
            int  sizeOfCodeHorizontal   = 0;
            int  sizeOfFinderVertical   = 0;
            int  sizeOfCodeVertical     = 0;
            bool b           = true;
            int  line        = 0;
            int  column      = 0;
            int  startLine   = 0;
            int  startColumn = 0;

            //Searching
            while (b)
            {
                column = 0;
                while (column < image.GetLength(1) && !image[line, column].isCloseToBlack)
                {
                    column++;
                }
                startColumn = column;
                startLine   = line;
                // For horizontal size
                while (column < image.GetLength(1) && image[startLine, column].isCloseToBlack)
                {
                    b = false;
                    sizeOfFinderHorizontal++;
                    column++;
                }
                // For Vertical size
                while (!b && line < image.GetLength(0) && image[line, startColumn].isCloseToBlack)
                {
                    sizeOfFinderVertical++;
                    line++;
                }
                if (!b)
                {
                    // Horizontal size
                    for (int j = image.GetLength(1) - 1; j >= 0 && sizeOfCodeHorizontal == 0; j--)
                    {
                        if (image[startLine, j].isCloseToBlack)
                        {
                            sizeOfCodeHorizontal = j - startColumn;
                        }
                    }
                    // Vertical Size
                    for (int j = image.GetLength(0) - 1; j >= 0 && sizeOfCodeVertical == 0; j--)
                    {
                        if (image[j, startColumn].isCloseToBlack)
                        {
                            sizeOfCodeVertical = j - startLine;
                        }
                    }
                }
                line++;
            }
            //Compute the size of a bit (finder is 7 pixels wide)
            int bitSizeHorizontal = sizeOfFinderHorizontal / 7;
            int bitSizeVertical   = sizeOfFinderVertical / 7;
            int approxSize        = sizeOfCodeHorizontal / bitSizeHorizontal;

            //Determine the version of QR based on the size
            if (approxSize < 23)
            {
                type = 1;
            }
            else
            {
                type = 2;
            }
            //Now read the QRCode but first Draw the Canvas
            DrawCanvas();
            //Read DAta
            string messageBits = ReadData(bitSizeHorizontal, bitSizeVertical, startLine, startColumn);

            // Get rid of the last seven bits if type 2
            if (type == 2)
            {
                messageBits = messageBits.Substring(0, 352);
            }
            Console.WriteLine(messageBits);
            // Get The Error count
            int eccCount = 7 * 8;

            if (type == 2)
            {
                eccCount = 10 * 8;
            }
            //Split error bits and message bits
            string errorBits = messageBits.Substring(messageBits.Length - eccCount, eccCount);

            messageBits = messageBits.Substring(0, messageBits.Length - eccCount);
            // Decode with Reed Solomon Algorithm
            byte[] messageBytes = BitsToByte(messageBits);
            byte[] errorBytes   = BitsToByte(errorBits);
            byte[] finalMessage = ReedSolomonAlgorithm.Decode(messageBytes, errorBytes, ErrorCorrectionCodeType.QRCode);
            messageBits = ByteToBit(finalMessage);
            // Assume the image is alphanumeric and get rid of the length
            messageBits = messageBits.Substring(4, messageBits.Length - 4);
            Decode_Message(messageBits);
        }