-
-
Notifications
You must be signed in to change notification settings - Fork 608
feat: Ability to scan both normal codes and inverted codes #1215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
dff1935
740b720
ebfe698
b1bb926
25e52d7
88b7b67
89d0f20
5ceb867
989f441
71d1e83
1e76615
c8f48b2
96becf0
d8512f4
62a728d
638c94b
b7080a6
47f8155
c1313ef
ebae80d
a386275
1debc4a
0b81241
46850cd
0277f9b
f1a60d1
a6cbfaf
6f45752
f420ab7
ab2021e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | |
|
||
var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates | ||
|
||
/// Analyze inverted image intervally to include both inverted and normal images | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
var intervalInvertImage: Bool = false | ||
private var invertImage: Bool = false // local to invert intervally | ||
|
||
private let backgroundQueue = DispatchQueue(label: "camera-handling") | ||
|
||
var standardZoomFactor: CGFloat = 1 | ||
|
@@ -120,6 +124,14 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | |
func requestPermission(_ result: @escaping FlutterResult) { | ||
AVCaptureDevice.requestAccess(for: .video, completionHandler: { result($0) }) | ||
} | ||
|
||
func convertCIImageToCGImage(inputImage: CIImage) -> CGImage? { | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
let context = CIContext(options: nil) | ||
if let cgImage = context.createCGImage(inputImage, from: inputImage.extent) { | ||
return cgImage | ||
} | ||
return nil | ||
} | ||
|
||
/// Gets called when a new image is added to the buffer | ||
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { | ||
|
@@ -136,10 +148,20 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | |
|
||
nextScanTime = currentTime + timeoutSeconds | ||
imagesCurrentlyBeingProcessed = true | ||
|
||
let ciImage = latestBuffer.image | ||
|
||
let image = VisionImage(image: ciImage) | ||
// Inversion | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
let uiImage : UIImage | ||
if (intervalInvertImage) { | ||
invertImage = !invertImage | ||
} | ||
if (invertImage) { | ||
let tempImage = self.invertImage(image: latestBuffer.image) | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
uiImage = tempImage | ||
} else { | ||
uiImage = latestBuffer.image | ||
} | ||
|
||
let image = VisionImage(image: uiImage) | ||
image.orientation = imageOrientation( | ||
deviceOrientation: UIDevice.current.orientation, | ||
defaultOrientation: .portrait, | ||
|
@@ -163,14 +185,15 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | |
} | ||
} | ||
|
||
mobileScannerCallback(barcodes, error, ciImage) | ||
mobileScannerCallback(barcodes, error, uiImage) | ||
} | ||
} | ||
} | ||
|
||
/// Start scanning for barcodes | ||
func start(barcodeScannerOptions: BarcodeScannerOptions?, cameraPosition: AVCaptureDevice.Position, torch: Bool, detectionSpeed: DetectionSpeed, completion: @escaping (MobileScannerStartParameters) -> ()) throws { | ||
func start(barcodeScannerOptions: BarcodeScannerOptions?, cameraPosition: AVCaptureDevice.Position, intervalInvertImage: Bool, torch: Bool, detectionSpeed: DetectionSpeed, completion: @escaping (MobileScannerStartParameters) -> ()) throws { | ||
self.detectionSpeed = detectionSpeed | ||
self.intervalInvertImage = intervalInvertImage | ||
if (device != nil || captureSession != nil) { | ||
throw MobileScannerError.alreadyStarted | ||
} | ||
|
@@ -355,6 +378,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | |
device.unlockForConfiguration() | ||
} catch(_) {} | ||
} | ||
|
||
func setIntervalInvertImage(_ intervalInvertImage: Bool) { | ||
self.intervalInvertImage = intervalInvertImage | ||
} | ||
|
||
/// Turn the torch on. | ||
private func turnTorchOn() { | ||
|
@@ -434,16 +461,30 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | |
/// Analyze a single image | ||
func analyzeImage(image: UIImage, position: AVCaptureDevice.Position, | ||
barcodeScannerOptions: BarcodeScannerOptions?, callback: @escaping BarcodeScanningCallback) { | ||
let image = VisionImage(image: image) | ||
image.orientation = imageOrientation( | ||
var uiImage = image | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
if (invertImage) { | ||
uiImage = self.invertImage(image: uiImage) | ||
} | ||
let visImage = VisionImage(image: uiImage) | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
visImage.orientation = imageOrientation( | ||
deviceOrientation: UIDevice.current.orientation, | ||
defaultOrientation: .portrait, | ||
position: position | ||
) | ||
|
||
let scanner: BarcodeScanner = barcodeScannerOptions != nil ? BarcodeScanner.barcodeScanner(options: barcodeScannerOptions!) : BarcodeScanner.barcodeScanner() | ||
|
||
scanner.process(image, completion: callback) | ||
scanner.process(visImage, completion: callback) | ||
} | ||
|
||
func invertImage(image: UIImage) -> UIImage { | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
let ciImage = CIImage(image: image) | ||
let filter = CIFilter(name: "CIColorInvert") | ||
|
||
filter?.setValue(ciImage, forKey: kCIInputImageKey) | ||
let outputImage = filter?.outputImage | ||
let cgImage = convertCIImageToCGImage(inputImage: outputImage!) | ||
|
||
return UIImage(cgImage: cgImage!, scale: image.scale, orientation: image.imageOrientation) | ||
} | ||
|
||
var barcodesString: Array<String?>? | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> { | |
this.formats = const <BarcodeFormat>[], | ||
this.returnImage = false, | ||
this.torchEnabled = false, | ||
this.intervalInvertImage = false, | ||
this.useNewCameraSelector = false, | ||
}) : detectionTimeoutMs = | ||
detectionSpeed == DetectionSpeed.normal ? detectionTimeoutMs : 0, | ||
|
@@ -82,6 +83,11 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> { | |
/// Defaults to false, and is only supported on iOS, MacOS and Android. | ||
final bool returnImage; | ||
|
||
/// Whether the image should be inverted in intervals (original - inverted - original…) | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
/// | ||
/// Defaults to false. | ||
|
||
final bool intervalInvertImage; | ||
RafaRuiz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
/// Whether the flashlight should be turned on when the camera is started. | ||
/// | ||
/// Defaults to false. | ||
|
@@ -278,6 +284,7 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> { | |
returnImage: returnImage, | ||
torchEnabled: torchEnabled, | ||
useNewCameraSelector: useNewCameraSelector, | ||
intervalInvertImage: intervalInvertImage, | ||
); | ||
|
||
try { | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -111,6 +111,11 @@ abstract class MobileScannerPlatform extends PlatformInterface { | |||||||||||
throw UnimplementedError('updateScanWindow() has not been implemented.'); | ||||||||||||
} | ||||||||||||
|
||||||||||||
/// Set inverting image colors in intervals (for negative Data Matrices). | ||||||||||||
|
/// Set inverting image colors in intervals (for negative Data Matrices). | |
/// Enable or disable the inverting of image colors. | |
/// | |
/// This is useful when working with negative-color Data Matrices. | |
/// See also: https://en.wikipedia.org/wiki/Negative_(photography) |
Uh oh!
There was an error while loading. Please reload this page.