Search code examples
c#qr-code

Retrieving two-dimensional array from QR code image


I need to retrieve a two-dimensional array from the image of QR code. Result must be like this:

{
    {1,1,1,1,1,1,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1},
    {1,0,1,1,1,0,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1},
    {1,0,1,1,1,0,1,0,0,0,0,0,1,0,1,0,1,1,1,0,1},
    {1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1},
    {1,0,0,0,0,0,1,0,1,1,1,0,0,0,1,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1},
    {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {1,1,0,1,0,0,1,1,0,0,1,1,1,0,1,1,1,0,1,1,0},
    {1,1,1,1,1,1,0,0,1,0,0,1,0,1,0,1,0,1,1,1,1},
    {0,1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1,1,0,1},
    {1,0,0,1,1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1},
    {0,1,1,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,1,0,0},
    {0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,1,0,1,0,0},
    {1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,1,1,0,1,0},
    {1,0,0,0,0,0,1,0,0,1,1,0,0,0,1,0,0,0,1,1,1},
    {1,0,1,1,1,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1},
    {1,0,1,1,1,0,1,0,1,0,0,0,0,1,1,1,0,0,0,1,1},
    {1,0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0,1,1,0,1},
    {1,0,0,0,0,0,1,0,1,0,1,1,1,0,0,1,0,1,0,0,0},
    {1,1,1,1,1,1,1,0,1,0,1,0,0,1,0,1,0,0,1,1,0}
}

C# program should take .bmp image, get qr code on it and return this qr code as two-dimensional array of "1" for black pixels and "0" for white pixels

Here is my code that takes bmp and returns text on it using MultiFormatReader from zxing lib

Bitmap originalBitmap = new Bitmap(pathOfBmp);

LuminanceSource source;
source = new BitmapLuminanceSource(originalBitmap);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap);


Console.WriteLine(result.Text);

But its not an array, just decoded text


Solution

  • Using 1 byte per pixel format with BMP file the code will look like this

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Drawing;
    
    namespace ConsoleApplication52
    {
        class Program
        {
            const string BMP_FILENAME = @"c:\temp\test.bmp";
    
            static void Main(string[] args)
            {
                Bitmap bitmap = new Bitmap(BMP_FILENAME);
    
                int rows = bitmap.Height;
                int columns = bitmap.Width;
    
                List<List<byte>> array = new List<List<byte>>();
    
                for(int row = 0; row < rows; row++)
                {
                    List<byte> rowArray = new List<byte>();
                    array.Add(rowArray);
                    for(int col = 0; col < columns; col++)
                    {
                        Color color = bitmap.GetPixel(col,row);
                        uint bits = (uint)color.ToArgb();
                        for (int bit = 31; bit >= 0; bit--)
                        {
                            uint mask = (uint)(1 << bit);
                            rowArray.Add((byte)((bits & mask) > 0 ? 1 : 0));
                        }
                    }
                }
            }
        }
    }
    

    If it is only one bit per pixel the code would look like this

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Drawing;
    
    namespace ConsoleApplication52
    {
        class Program
        {
            const string BMP_FILENAME = @"c:\temp\test.bmp";
    
            static void Main(string[] args)
            {
                Bitmap bitmap = new Bitmap(BMP_FILENAME);
    
                int rows = bitmap.Height;
                int columns = bitmap.Width;
    
                List<List<byte>> array = new List<List<byte>>();
                uint mask = 0x80; // or 0x8000 for 32 bits
                for(int row = 0; row < rows; row++)
                {
                    List<byte> rowArray = new List<byte>();
                    array.Add(rowArray);
                    for(int col = 0; col < columns; col++)
                    {
                        Color color = bitmap.GetPixel(col,row);
                        uint bits = (uint)color.ToArgb();
                        rowArray.Add((byte)((bits & mask) > 0 ? 1 : 0));
                    }
                }
            }
        }
    }