Latest Info :
After reminded by @Michael,
I successfully capture and decode the QR code by using the
zxingnet-88246\trunk\Clients\WindowsFormsDemo
EmguCVDemo (successful decode QR code in camera frame today)
I will try to compare the difference between the Demo code and my code. Thanks Michael, so happy to successfully decode it.
p/s: those sample codes work with net4.0 zxing.dll but not the net4.5 zxing.dll
Old questions:
By using Zxing.Net, I can decode original image of the QR code encoded by ZXing.Net.
But when I obtain the image from Emgu.CV capture, it cannot be decoded by ZXing.Net even I
try to crop, resize and add canvas size.
But, the magic is the Android QR code scanner CAN scan those QR code even directly from camera capture. I tried to analyzed the Android source code but I found nothing special.
I wonder if the Android version one is using camera auto-focus function?
Below is my code:
DecoderResult decoderResult;
Bitmap bitmap = new Bitmap(@"C:\testfunny678.bmp");
LuminanceSource source = new BitmapLuminanceSource(bitmap);
//
BinaryBitmap binBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
try
{
//null Hashable Hints
DetectorResult detectorResult = new Detector(binBitmap.BlackMatrix).detect(null);
Result result = decoder.decode(binBitmap);
//decoderResult = decoder.decode(detectorResult.Bits,null);
//points = detectorResult.Points;
//Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
if (result.Text != null)
{
//QR_CODE
//MessageBox.Show("format is: " + result.BarcodeFormat);
MessageBox.Show("result is: " + result.Text);
}
else
{
MessageBox.Show("bitmap is null");
}
}
//com.google.zxing.ReaderException: Exception of type 'com.google.zxing.ReaderException' was thrown.
// at com.google.zxing.qrcode.detector.FinderPatternFinder.selectBestPatterns() in d:\Temp\zxing-2.1\csharp\qrcode\detector\FinderPatternFinder.cs:line 602
// at com.google.zxing.qrcode.detector.FinderPatternFinder.find(Hashtable hints) in d:\Temp\zxing-2.1\csharp\qrcode\detector\FinderPatternFinder.cs:line 238
// at com.google.zxing.qrcode.detector.Detector.detect(Hashtable hints) in d:\Temp\zxing-2.1\csharp\qrcode\detector\Detector.cs:line 90
// at qrcode.Form1.Decode3() in c:\Users\User\Documents\Visual Studio 2013\Projects\qrcode\qrcode\Form1.cs:line 139
catch (Exception e)
{
//MessageBox.Show(e.ToString());
}
My code can decode this
Camera capture like this
After crop,resize and add canvas, it becomes like this (testfunny678.bmp)
I added canvas at the first QR code picture because I found of the QR code surrounded by black colour, it cannot be decoded even by Android QR code decoder.
Old version of my code using HybridBinarizer cannot decode the first QR code.
LuminanceSource source = new RGBLuminanceSource(GetRGBValues(bitmap), bitmap.Width, bitmap.Height);
BinaryBitmap binBitmap = new BinaryBitmap(new HybridBinarizer(source));
My ultimate target is decode the QR code directly from camera (2nd QR code), but if I can decode the third QR code, I also feel happy. My friend tell me to sharpen the third image so that ZXing decoder and decode the third QR code.
By the way, I can detect the QR code existence (Found at points (23.5, 76.5), (23.5, 23.5), (75, 24.5))
of THIRD QR code via this two function
public string Detect(Bitmap bitmap)
{
try
{
ZXing.LuminanceSource source = new RGBLuminanceSource(GetRGBValues(bitmap), bitmap.Width, bitmap.Height);
var binarizer = new HybridBinarizer(source);
var binBitmap = new BinaryBitmap(binarizer);
BitMatrix bm = binBitmap.BlackMatrix;
Detector detector = new Detector(bm);
DetectorResult result = detector.detect();
string retStr = "Found at points ";
foreach (ResultPoint point in result.Points)
{
retStr += point.ToString() + ", ";
}
return retStr;
}
catch
{
return "Failed to detect QR code.";
}
}
private byte[] GetRGBValues(Bitmap bmp)
{
// Lock the bitmap's bits.
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
bmp.UnlockBits(bmpData);
return rgbValues;
}
But even I tried to use the DetectorResult.Points from Detect() function by changing Detect() function to return the DetectorResult for Decoder, it is still fail at the decoder part by having null decoderResult.
public DetectorResult Detect(Bitmap bitmap)
//public string Detect(Bitmap bitmap)
{
try
{
ZXing.LuminanceSource source = new RGBLuminanceSource(GetRGBValues(bitmap), bitmap.Width, bitmap.Height);
var binarizer = new HybridBinarizer(source);
var binBitmap = new BinaryBitmap(binarizer);
BitMatrix bm = binBitmap.BlackMatrix;
Detector detector = new Detector(bm);
DetectorResult result = detector.detect();
return result;
//string retStr = "Found at points ";
//foreach (ResultPoint point in result.Points)
//{
// retStr += point.ToString() + ", ";
//}
//return retStr;
}
catch
{
//return "Failed to detect QR code.";
return null;
}
}
void Decode3()
{
//System.Collections.Hashtable hints = null;
DecoderResult decoderResult;
Bitmap bitmap = new Bitmap(@"C:\testfunny678.bmp");
LuminanceSource source = new BitmapLuminanceSource(bitmap);
BinaryBitmap binBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
ResultPoint[] points;
ZXing.QrCode.Internal.Decoder decoder = new ZXing.QrCode.Internal.Decoder();
//ZXing.MultiFormatReader decoder = new ZXing.MultiFormatReader();
try
{
DetectorResult detectorResult = new Detector(binBitmap.BlackMatrix).detect(null);
//DetectorResult detectorResult = Detect(bitmap);
//Result result = decoder.decode(binBitmap);
//null decoderResult here
decoderResult = decoder.decode(detectorResult.Bits,null);
points = detectorResult.Points;
Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
if (result.Text != null)
{
MessageBox.Show("result is: " + result.Text);
}
else
{
MessageBox.Show("bitmap is null");
}
}
catch (Exception e)
{
//MessageBox.Show(e.ToString());
}
}
Any suggestion or correction to successfully decode the 2nd QR code and 3rd QR code with ZXing.NET QR code decoder is welcome, thank you.