Reputation: 2525
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;
}
}
Upvotes: 1
Views: 370
Reputation: 50366
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;
}
Upvotes: 1
Reputation: 20595
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);
}
Upvotes: 1
Reputation: 1245
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.
Upvotes: 0