private Result[] decodeMulti(Uri uri, IDictionary<DecodeHintType, object> hints) { Bitmap image; try { image = (Bitmap)Bitmap.FromFile(uri.LocalPath); } catch (Exception) { throw new FileNotFoundException("Resource not found: " + uri); } LuminanceSource source; if (config.Crop == null) { source = new BitmapLuminanceSource(image); } else { int[] crop = config.Crop; source = new BitmapLuminanceSource(image).crop(crop[0], crop[1], crop[2], crop[3]); } BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); if (config.DumpBlackPoint) { dumpBlackPoint(uri, image, bitmap); } MultiFormatReader multiFormatReader = new MultiFormatReader(); GenericMultipleBarcodeReader reader = new GenericMultipleBarcodeReader( multiFormatReader); Result[] results = reader.decodeMultiple(bitmap, hints); if (results != null && results.Length > 0) { if (config.Brief) { Console.Out.WriteLine(uri + ": Success"); } else { foreach (var result in results) { ParsedResult parsedResult = ResultParser.parseResult(result); Console.Out.WriteLine(uri + " (format: " + result.BarcodeFormat + ", type: " + parsedResult.Type + "):\nRaw result:\n" + result.Text + "\nParsed result:\n" + parsedResult.DisplayResult); Console.Out.WriteLine("Found " + result.ResultPoints.Length + " result points."); for (int i = 0; i < result.ResultPoints.Length; i++) { ResultPoint rp = result.ResultPoints[i]; Console.Out.WriteLine(" Point " + i + ": (" + rp.X + ',' + rp.Y + ')'); } } } return results; } else { Console.Out.WriteLine(uri + ": No barcode found"); } return null; }
/// <summary> /// Tries to decode barcodes within an image which is given by a luminance source. /// That method gives a chance to prepare a luminance source completely before calling /// the time consuming decoding method. On the other hand there is a chance to create /// a luminance source which is independent from external resources (like Bitmap objects) /// and the decoding call can be made in a background thread. /// </summary> /// <param name="luminanceSource">The luminance source.</param> /// <returns></returns> private Result[] DecodeMultiple(LuminanceSource luminanceSource) { var results = default(Result[]); var binarizer = CreateBinarizer(luminanceSource); var binaryBitmap = new BinaryBitmap(binarizer); var rotationCount = 0; var rotationMaxCount = 1; MultipleBarcodeReader multiReader = null; if (AutoRotate) { Options.Hints[DecodeHintType.TRY_HARDER_WITHOUT_ROTATION] = true; rotationMaxCount = 4; } var formats = Options.PossibleFormats; if (formats != null && formats.Length == 1 && formats[0] == BarcodeFormat.QR_CODE) { multiReader = new QRCodeMultiReader(); } else { multiReader = new GenericMultipleBarcodeReader(Reader); } for (; rotationCount < rotationMaxCount; rotationCount++) { results = multiReader.decodeMultiple(binaryBitmap, Options.Hints); if (results == null) { if (TryInverted && luminanceSource.InversionSupported) { binaryBitmap = new BinaryBitmap(CreateBinarizer(luminanceSource.invert())); results = multiReader.decodeMultiple(binaryBitmap, Options.Hints); } } if (results != null || !luminanceSource.RotateSupported || !AutoRotate) break; binaryBitmap = new BinaryBitmap(CreateBinarizer(luminanceSource.rotateCounterClockwise())); } if (results != null) { foreach (var result in results) { if (result.ResultMetadata == null) { result.putMetadata(ResultMetadataType.ORIENTATION, rotationCount * 90); } else if (!result.ResultMetadata.ContainsKey(ResultMetadataType.ORIENTATION)) { result.ResultMetadata[ResultMetadataType.ORIENTATION] = rotationCount * 90; } else { // perhaps the core decoder rotates the image already (can happen if TryHarder is specified) result.ResultMetadata[ResultMetadataType.ORIENTATION] = ((int)(result.ResultMetadata[ResultMetadataType.ORIENTATION]) + rotationCount * 90) % 360; } } OnResultsFound(results); } return results; }