1

I am having trouble wrapping my head around this and wanted some input on this. So I am reading in a scanned PDF document that has a QR code in it which is always located on the top left corner of the document.

Due to the fact that scanning files might change the orientation of the document I am checking the top left corner of the document to see if it has the QR code and if not I will rotate the document and check the left corner again. Purpose of this because in the QR code is on the left top corner then the document is in proper format for my requirements.

How could I change my following code so that it gets the document checks for a QR code - if not found rotate the whole document check again and continue until the QR code has been found. Also should I just rotate by 90 in a loop rather than 90 - 180 - 270.

using (var fullImg = new Bitmap(workGif))
{
    var bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, 375, 375), fullImg.PixelFormat);
    Bitmap result = fullImg;
    if (Process(bandImg) == null)
    {
        fullImg.RotateFlip(RotateFlipType.Rotate270FlipNone);
        bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);
        if (Process(bandImg) == null)
        {
            fullImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
            bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);

            if (Process(bandImg) == null)
            {
                fullImg.RotateFlip(RotateFlipType.Rotate180FlipNone);
                bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);
            }
         }
    }
    bandImg.Save(@"C:\NewImageTest.png");
    string QRinfo = Process(bandImg);
    MessageBox.Show(QRinfo);
}

Process Method I pass the image in this method to check and see if there is a QR code to be read.

public string Process(Bitmap bitmap)
{
    var reader = new com.google.zxing.qrcode.QRCodeReader();

    try
    {
        LuminanceSource source = new RGBLuminanceSource(bitmap, bitmap.Width, bitmap.Height);
        var binarizer = new HybridBinarizer(source);
        var binBitmap = new BinaryBitmap(binarizer);
        return reader.decode(binBitmap).Text;
    }
    catch (Exception e)
    {
        return null;
    }
}
2
  • What is result and where does it come from? Commented Mar 20, 2013 at 1:48
  • @cdhowie missed to put it in - result is the image of the whole file page. Commented Mar 20, 2013 at 1:50

3 Answers 3

1

Woudn't something like this work for you? There are only four possible orientations of the document, so you have to loop at most four times. Each loop you rotate the image by 90 degrees. Once you've established that the QR code is in the top-left corner, you can break out of the loop. Then you can process the QR code or do whatever you want with it.

public void Do(string workGif)
{
    // ...
    string qrInfo;
    using (var fullImg = new Bitmap(workGif))
    {
        for (int i = 0; i < 4; i++)
        {
            // Does the image contain a QR code?
            qrInfo = Process(fullImg);
            if (qrInfo = null)
                // No QR code found. Rotate the image.
                fullImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
            else
                // QR code found. Break out of the loop.
                break;
        }
        if (qrInfo == null)
        {
            throw new InvalidOperationException(
                "The document contains no QR code.");
        }
    }
    MessageBox.Show(qrInfo);
    // ...
}

You can move the code that takes the corner image of the source image to the Process method.

private Image GetCornerImage(Image sourceImage)
{
    return sourceImage.Clone(new Rectangle(0, 0, 375, 375), sourceImage.PixelFormat);
}

public string Process(Bitmap bitmap)
{
    var cornerImg = GetCornerImage(bitmap);

    var reader = new com.google.zxing.qrcode.QRCodeReader();
    LuminanceSource source = new RGBLuminanceSource(
        cornerImg, cornerImg.Width, cornerImg.Height);
    var binarizer = new HybridBinarizer(source);
    var binBitmap = new BinaryBitmap(binarizer);
    return reader.decode(binBitmap).Text;
}
Sign up to request clarification or add additional context in comments.

7 Comments

I just tried this and everything makes sense but i realized that my var bandImg is only looking at the specific corner and when rotating it will rotate that corner and not the whole page so i changed in the forloop to fullImage.RotateFlip... but after testing it only works when the qr code is already in proper format (left top corner)
Also for if(HasProperQRCode(bandImg)) I am actually using Process(bandImg) which i posted its code above. I use it to read the qr code if exists.
Really appreciate the help. I am still getting an error when i pass in a file where the qr code is not on the top left corner. but if i pass in a file where the qr code is in the top left corner it works. i will work with this and see what i could alter
@Amina You probably get an error from the QRCodeReader you're using. Read the documentation and find out, for example, if there is a way to use it without having to catch an exception when there is no QR code. Maybe a trydecode method that returns a boolean?
I will look into it now - thanks. I will debug and see what is going on because it used to work with all the if statements that i had.
|
1

This should work fine ;

using (var fullImg = new Bitmap(workGif))
{
    var bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, 375, 375), fullImg.PixelFormat);
    int i = 0;
    while(Process(bandImg) == null)
    {
        if (i == 1)
            fullImg.RotateFlip(RotateFlipType.Rotate270FlipNone);
        else if (i == 2)
            fullImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
        else if (i== 3)
            fullImg.RotateFlip(RotateFlipType.Rotate180FlipNone);

            /*
                 Another way in which Rotation Degree can be done
                 First time it rotate by 270, then by 180 & then by 90
                 int i must be initialized with 1
                 int degree_to_rotate = 360 - ((4 - i) * 90)
            */

        bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);
        i++;
    }
    bandImg.Save(@"C:\NewImageTest.png");
    string QRinfo = Process(bandImg);
    MessageBox.Show(QRinfo);
}

3 Comments

ok so that i just understand - Process(bandImg) is the method used to check and see if there is a qr code to read. If not then the page should be rotated and the new rotated page is passed in Process() again to check. If while(Process(bandImg) != null) then it break out the loop and not rotate if it is null. should it be while(Process(bandImg) == null) ?
@Amina - Sorry, misread the code in hurry, yes it should be ==
for some odd reason it works for a file where the qr code is already in right position (top left corner) if i pass in a file where the qr code is on the bottom right corner it gives me an error
0

If you are doing the same checks in every rotation, there is no reason not to use a loop. Just make sure you keep track of the number of rotations performed or you will be stuck in an infinite loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.