mikebuss / mtbbarcodescanner Goto Github PK
View Code? Open in Web Editor NEWA lightweight, easy-to-use barcode scanning library for iOS 8+
License: MIT License
A lightweight, easy-to-use barcode scanning library for iOS 8+
License: MIT License
First off, great library!
The problem I am having is that when I read VIN barcodes from vehicles that are not in the QR format, it wants to throw a l
in front of each vin at the very beginning. Everything after that is read in correctly but I'm not sure why it is throwing that l
in at the beginning.
Here is a sample that it does it on:
I have also did it on a vehicle that is owned by my family that is also not in the QR format and it did the exact same thing.
Any help would be appreciated!
Thanks
Hi Mike,
I'm using your scanner in one of my apps, and it is working great for iphone 4s and 5. However, many users of the app are complaining about it not working well on iphone 6. I have tried it on iPhone 6, and my experience is that sometimes it works fine, and sometimes it does not react to the barcode at all.
Do you recognize the problem?
Do you have any recommended fixes or things I might try out to make it work better on iPhone6?
It works really well on iphone 4s, so it is making me very confused that it is not working properly on iphone 6.
Best,
Kasper
startScanningWithResultBlock
takes a while to get camera ready to use especially when it comes to a full screen preview view. I want to show a preparing indicator UIActivityIndicatorView before call startScanningWithResultBlock
and get notified when the camera is ready and shown to use so I can stop animating that indicator. This user experience is better if there's a loading indicator while waiting.
The following lines of code is just preparing the camera but it takes enough time to make users wait.
if (!self.hasExistingSession) {
AVCaptureDevice *captureDevice = [self newCaptureDeviceWithCamera:self.camera];
self.session = [self newSessionWithCaptureDevice:captureDevice];
self.hasExistingSession = YES;
}
[self.session startRunning];
Instruments shows this.
I don't know how to translate that 22.0ms CPU time into real time but it indeed made me wait.
Since there's no delegate in MTBBarcodeScanner, I'm thinking about adding a block property in the header file.
@property (nonatomic, copy) void (^didStartScanningBlock)();
And call this block in MTBBarcodeScanner like below.
- (void)startScanningWithResultBlock:(void (^)(NSArray *codes))resultBlock {
// ...
[self.session startRunning];
// ...
// Last three line
if (self.didStartScanningBlock) {
self.didStartScanningBlock();
}
}
What do you guys think?
When attempting to scan a barcode for the first time, the permission dialog pops up but scanningIsAvailableAndAllowed
returns YES immediately, which allows startScanningWithResultBlock
to be called.
I'd like to add a requestCameraPermissionWithSuccess:(void (^)(BOOL success))successBlock
method so we can start scanning after permission has been granted.
It would be great if you give support for Carthage.
When I freezeCapture()
on a successful scan, sometimes it scans the same barcode a second time and the callback gets called again. So, is freeze capture a safe way to stop capturing and then use unfreeze when ready to restart? Or should I always use stopScanning()?
When we scans a UPC barcode, the iOS device adds an extra zero in front of the barcode number
Hi,
I was playing around with the library and I found out that changing the focusMode to AutoFocus improves a lot the usability of the scanner.
Testing with iPhone 5 iOS 10 GM was really hard to focus on a QR code even if the autoFocusRangeRestriction
is set to AVCaptureAutoFocusRangeRestrictionNear
.
// Focus on the center of the image
if ([deviceInput.device respondsToSelector:@selector(isFocusPointOfInterestSupported)] &&
deviceInput.device.isFocusPointOfInterestSupported) {
self.initialFocusPoint = deviceInput.device.focusPointOfInterest;
deviceInput.device.focusPointOfInterest = CGPointMake(kFocalPointOfInterestX, kFocalPointOfInterestY);
deviceInput.device.focusMode = AVCaptureFocusModeContinuousAutoFocus;
}
Cheers!
I'm using MTBarcode for a Swift project that requires support for iOS 7. There is just one line that should be added to keep working on it.
MTBarcodeScanner.m line 356
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
self.stillImageOutput.highResolutionStillImageOutputEnabled = YES;
}
I've replaced them to enable support for iOS 7, but every time I update my CocoaPods or setup in another computer I should make this change manually. Can you please add this change to master branch?
Data Matrix codes are not recognized when using the front camera. They are, however, recognized if the Data Matrix code is inverted (either using an image manipulation program such as Photoshop, OR when the code is read through a mirror... which took some dexterity to pull off). I suspect this is due to some image-flipping closer to the hardware, and the fact that Data Matrix codes have an orientation.
Might this bug exist in your library, or shall I submit a radar with Apple?
Can you please add the ability to scan barcodes from images in user library ?
Hi,
I am using your code via the iBarcode library wrapper in the AnyWhereSoftware B4i product.
For reference you may like to view:
[]https://www.b4x.com/index.html
[]https://www.b4x.com/android/forum/threads/ibarcode-library.47354/
This wrapper has recently been enhanced to incorporate the MTBTorchModeOff/ MTBTorchModeOn/ MTBTorchModeAuto features, see this thread:
Everything works brilliantly except for one thing - when MTBTorchModeAuto is used the torch never turns on, even in total darkness.
I'd be appreciative of any help/ suggestions/ fixes you may be able to conjure up.
MTBBarcodeScanner.m
self.stillImageOutput.highResolutionStillImageOutputEnabled = YES;
should be
if ([self.stillImageOutput respondsToSelector:@selector(isHighResolutionStillImageOutputEnabled)]) { self.stillImageOutput.highResolutionStillImageOutputEnabled = YES; }
Hi,
The Scanner has beeen working marvelousely for me.
Unfortunately on iOS 9 if you don't set the scanRect
property it fails to deliver scan results.
This is easily reproducable in the basic example. It simply does not scan. The advanced example on the other hand scans without a flaw. When i set the scanRect
in the basic example it starts working again.
I see high rate crash on captureOutput:didOutputMetadataObjects:fromConnection:
in my crash report. I use 1.9.1 MTBBarcodeScanner with iOS 7 support.
n | file | selector |
---|---|---|
0 | myApp | [MTBBarcodeScanner captureOutput:didOutputMetadataObjects:fromConnection:](in myApp) (MTBBarcodeScanner.m:367) |
1 | AVFoundation | +[AVOutputSettings outputSettingsWithOutputSettingsDictionary:](in AVFoundation) + 69 |
2 | libdispatch.dylib | 0x000000018e179833 (in libdispatch.dylib) |
3 | libdispatch.dylib | 0x000000018e17981f (in libdispatch.dylib) |
4 | libdispatch.dylib | _Xwakeup_runloop_thread (in libdispatch.dylib) + 55 |
5 | CoreFoundation | __CFArrayCopyDescription (in CoreFoundation) + 445 |
6 | CoreFoundation | _CFSTFeatureCounterCreate (in CoreFoundation) + 105 |
7 | CoreFoundation | CFBasicHashGetCountOfKey (in CoreFoundation) + 2303 |
8 | CoreFoundation | CFBasicHashGetCountOfKey (in CoreFoundation) + 1763 |
9 | GraphicsServices | __Initialize_block_invoke (in GraphicsServices) + 1079 |
10 | UIKit | -[UIImageView startAnimating](in UIKit) + 473 |
11 | myApp | main (in myApp) (main.m:17) |
12 | libdyld.dylib | 0x000000018e195ab7 (in libdyld.dylib) |
I analysed this exception, and I found that the method captureOutput:didOutputMetadataObjects:fromConnection:
is called multiples times(As Apple documentation says) even after that stopScanning was executed. Then resultBlock is nil
.
Hi
Will it scan the QR code in a JailBroken device?
Thanks
Fatal Exception: NSInvalidArgumentException
*** Can't add a nil AVCaptureInput
This crash happened only one time. iPad 4. iOS 8.3.0.
I don't have an iPad 4. Don't know how to reproduce it either.
Fabric shows below.
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x2b063fef __exceptionPreprocess
1 libobjc.A.dylib 0x39313c8b objc_exception_throw
2 AVFoundation 0x29b7a92b -[AVCaptureSession _addInputWithNoConnections:]
3 AVFoundation 0x29b7a20b -[AVCaptureSession addInput:]
4 ?????? 0x7bb8f5 -[MTBBarcodeScanner setDeviceInput:session:] (MTBBarcodeScanner.m:544)
5 ?????? 0x7bae3d -[MTBBarcodeScanner newSessionWithCaptureDevice:] (MTBBarcodeScanner.m:410)
6 ?????? 0x7ba1f1 -[MTBBarcodeScanner startScanningWithResultBlock:] (MTBBarcodeScanner.m:244)
7 ?????? 0x4d9984 ScanCodeViewController.(viewDidAppear(Bool) -> ()).(closure #1) (ScanCodeViewController.swift:164)
8 libdispatch.dylib 0x3987e2e3 _dispatch_call_block_and_release
9 libdispatch.dylib 0x3987e2cf _dispatch_client_callout
10 libdispatch.dylib 0x39881d2f _dispatch_main_queue_callback_4CF
11 CoreFoundation 0x2b029609 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
12 CoreFoundation 0x2b027d09 __CFRunLoopRun
13 CoreFoundation 0x2af74201 CFRunLoopRunSpecific
14 CoreFoundation 0x2af74013 CFRunLoopRunInMode
15 GraphicsServices 0x32741201 GSEventRunModal
16 UIKit 0x2e718a59 UIApplicationMain
17 ?????? 0x179fef main (main.m:14)
18 libdyld.dylib 0x3989faaf start
Just one last question! How do I know what type of code I just read? Because if it's a Url (Qr Code) I want to do something and if it's another type I want to do another action. I'm using swift. Thank you very much.
Hello Sir,
Thanks for this amazing library. I am trying to scan Aztec qr code but i am not able to do that so i like to know that weather i can read the Aztec qr code using this library or not?
Thanks,
Nothing happens after calling startScanningWithResultBlock:
on iOS9.
Hi Mike,
I don't know much about objectiv C but i work a lot with cordova and i wanted to ask if you had an idea on how to port your scanner to cordova.... I tried but i failed like a noob ;)
We're scanning VIN barcodes, both 1D and 2D, so I set the MTBBarcodeScanner to scan for types: AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeDataMatrixCode.
In my testing, it doesn't seem like white-on-black 2D barcodes are supported currently, though 1D barcodes seem to work well either black-on-white or white-on-black.
Is this expected behavior? The only reason I'm not 100% sure is because the one 2D barcode I have that's white-on-black also has the issue of not being 100% easily visible, so I'm not positive where the issue is.
If it's a known problem, are there any thoughts on how we might try to scan white-on-black 2D barcodes? I know this library is relying on Apple's built-in decoding (at least, last time I looked through the source code), but was thinking perhaps there's a way to internally try scanning a few frames of video after inverting the colors, to try and catch edge cases like this?
How Would I use this library in swift?
Since there is no ability to access the internals of the scanner (AVCaptureSession, AVCaptureDevice), it is technically impossible to extend the library to add tap to focus.
Is there any scope for getters and setters for the AVCaptureSession and AVCaptureDevice to be made public?
Cheers
I've got an app that uses MTBBarcodeScanner
and an UIImagePickerController
and ran into a few auto focus issues. Please see my focus_bug_demo branch for an illustration.
For all cases you need to restart the app to reproduce the effects.
Everything is consistent on my iPad Air and iPad 4.
It seems to me that line 335 in MTBBarcodeScanner.m
newCaptureDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;
is not applied properly for the current session but seems to persist for the UIImagePickerSession
. Removing the line results in the last two scenarios performing like to the ones above. However, I'm guessing the end of the last scenario is actually the desired behavior of line 335, is it?
I'm not even sure this is a MTBBarcodeScanner
issue or rather an iOS bug, but since we can't fix iOS MTBBarcodeScanner
should work around the issue.
Maybe changing the autoFocusRangeRestriction
back to AVCaptureAutoFocusRangeRestrictionNone
in stopScanning
is an option?
In my particular use-case, I'd like to capture and save a photo of the scanned barcode. My plan was to freeze the feed, save the photo and then unfreeze the feed again.
I can do this with a screenshot, but I'd rather save the actual photo from AVFoundation. If I create a pull request that does this and expose it via a single captureFrame method, is that something you would want to merge into the library?
// .h
/// Return a BOOL value that specifies whether the current capture device has a torch
- (BOOL) hasTorch;
// .m
- (BOOL) hasTorch {
return self.currentCaptureDeviceInput.device.hasTorch;
}
I think it's necessary to add this method.
Or make the current capture device a readonly property.
A torch toggle button should not be shown on an iPad and this method is needed to hide the torch toggle button.
I am having this error everytime i restart the Scaning and its stops working for capturing the Barcode.
func scanningStart(){
self.scanner.startScanningWithResultBlock { (codes) -> Void in
self.scanner.stopScanning()
// Doing my task here and after that
self.scanner.startScanning()
})
}
scanner.scanRect = viewIntrest.frame
}
On the iPad2 (i.e., the first iPad with a camera), -(AVCaptureDevice*)captureDevice throws an exception. It appears that the capture device respondsToSelector:@selector(setAutoFocusRangeRestriction:), BUT does so by throwing an exception because autoFocus is not supported.
The following code avoids the exception and does result in a valid barcode being retired:
- (AVCaptureDevice *)captureDevice {
if (!_captureDevice) {
NSError *lockError = nil;
_captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([_captureDevice lockForConfiguration:&lockError] == YES) {
if ([_captureDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
// Prioritize the focus on objects near to the device
if ([_captureDevice respondsToSelector:@selector(setAutoFocusRangeRestriction:)]) {
_captureDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;
}
// Focus on the center of the image
if ([_captureDevice respondsToSelector:@selector(setFocusPointOfInterest:)]) {
_captureDevice.focusPointOfInterest = CGPointMake(kFocalPointOfInterestX, kFocalPointOfInterestY);
}
}
[_captureDevice unlockForConfiguration];
}
}
return _captureDevice;
}
I created a build of my app with the iOS 10 SDK and submitted it to iTunes Connect and got the following rejection a few minutes later in an automated email:
This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
I was able to track down the cause of the rejection to this line:
return [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
That is, I tried replacing that line with return YES;
and the submission was accepted. I take it that an app that makes any UIImagePickerController call (even if it’s not actually requesting access to the user’s photo library) must include an entry for NSPhotoLibraryUsageDescription in its Info.plist. I sent an email to Apple developer support to confirm that behavior. I’ll report back if I hear anything.
If that is the case, perhaps replacing that line with the following would work:
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] != nil;
The documentation for that method only says for its return value:
The default device used to capture data of the type indicated by mediaType.
But the header says for its return value:
The default device with the given media type, or nil if no device with that media type exists.
I’ve confirmed that simulators return nil. It looks like the most recent device that doesn’t have a camera is a third generation iPod touch and it maxes out at iOS 5.1.1 (https://en.wikipedia.org/wiki/List_of_iOS_devices) so I didn’t test this on an actual device that doesn’t have a camera.
I am using MTBBarcodeScanner for reading ITF barcodes, but it doesn't read correctly Brazilian Bills with 47 digits.
A sample PDF (for printing) is available here (https://drive.google.com/file/d/0ByQMtFUGwDRBWnZObkFBcDR1RVk/edit?usp=sharing) . The barcode sequence number is on the top of the bill (a long sequence of numbers separeted by point and space).
For some reason, the scanner's video view does not completely fill the layer that I supply, there's about a centimeter (on my iPhone 6) on one edge of the screen that's just black. When I debug it, though, my view is definitely filling the entire screen. But for some reason, the video layer isn't.
At the same time, the orientation of the video itself is wrong (and sort of looks zoomed in). So if I'm holding the phone in landscape, the video is like I'm looking at the top or bottom half of a PORTRAIT-oriented video view. So if I start panning, instead of the video moving side-to-side, it's moving vertically. Very strange.
My guess is I'm doing something wrong, because when I first started integrating MTBBarcodeScanner, it wasn't doing this. But I've been working on it all day and can't figure out what's wrong. So I thought I'd check and see if the symptoms I'm describing are obvious to anyone? :-)
I'am setting the scanRect, but after orientation change and setting it again with the adjusted coordinates, the scanning stops working
I have an old app which is not using auto layout. I would like to have a preview view covering the whole screen. It works fine on iPhones, but it doesn't work on an iPad after changing the rotation once (initially the whole screen is covered).
If I don't pass the preview view to MTBBarscodeScanner's initializer the view always covers the whole screen.
Crash in MTBBarcodeScanner.m
at the line below.
self.stillImageOutput.highResolutionStillImageOutputEnabled = YES;
highResolutionStillImageOutputEnabled
can only be used on iOS 8 or later.
if ([self.stillImageOutput respondsToSelector:@selector(setHighResolutionStillImageOutputEnabled:)]) {
self.stillImageOutput.highResolutionStillImageOutputEnabled = YES;
}
Maybe the code above can solve it. But I'm not sure if there's some other issues.
When I try to use the example code with basic view controller and I switch Camera permission in Settings app, it makes crash the app.
First of all, Thanks for the Lib
I have few questions like AVCaptureSession Interruption.
Some time Session being stop after few seconds and was unable to detect the error, i have put the Debug points in this lib but nothing fire and camera stops scanning, So after little bit more research i have found one thing that some notifications will be called like
- AVCaptureSessionRuntimeErrorNotification
- AVCaptureSessionInterruptionEndedNotification
- AVCaptureSessionWasInterruptedNotification
And after adding this Observers in my controller i came up with this error in my Log
NSConcreteNotification 0x13f1dc0f0 {name = AVCaptureSessionRuntimeErrorNotification; object = <AVCaptureSession: 0x13f506680 [AVCaptureSessionPresetHigh]>
<AVCaptureDeviceInput: 0x13dfc4ae0 [Back Camera]> -> <AVCaptureStillImageOutput: 0x13f360c50>
<AVCaptureDeviceInput: 0x13dfc4ae0 [Back Camera]> -> <AVCaptureVideoPreviewLayer: 0x13f182030>
<AVCaptureDeviceInput: 0x13dfc4ae0 [Back Camera]> -> <AVCaptureMetadataOutput: 0x13f35c610>; userInfo = {
AVCaptureSessionErrorKey = "Error Domain=AVFoundationErrorDomain Code=-11800 \"The operation could not be completed\" UserInfo={NSUnderlyingError=0x13f1de2f0 {Error Domain=NSOSStatusErrorDomain Code=-16811 \"(null)\"}, NSLocalizedFailureReason=An unknown error occurred (-16811), NSLocalizedDescription=The operation could not be completed}";
}}
So My question is
To reproduce this issue in your demo you can just go to basic example and Click start scanning and wait for some minutes or use it for some minutes.this method will fire and session will stop scanning.Thanks
We have a large QR, which is quite problematic to recognise with using video, however, from a single photo it could be recognised better
there could be a functionality for taking a picture and than analysing it
Hi Mike,
I'm calling stopScanner on viewWillDisappear then running startScanningWithResultBlock in viewWillAppear. It works fine before I call stopScanner, but as soon as thats been called startScanningWithResultBlock doesnt work anymore.
Cheers
Charlie
There seems to be a slight issue with DataMatrix codes and using a scanRect.
Steps to reproduce:
Perform the above steps with a QR Code, and see that it is detected no matter where it is positioned in the scan rect.
I am not sure if this is an issue with this library or an issue in Apple's implementation of QR decoding.
Hi, I am unable to build the example project. I am getting this error:
diff: /../Podfile.lock: No such file or directory
diff: /Manifest.lock: No such file or directory
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
Here is a screenshot of the error:
I just downloaded the zip of the current GitHub code and tried to build and run the example project. I tried installing cocoapods and running through some of the steps in these stackoverflow posts, http://stackoverflow.com/questions/17072396/cocoapods-errors-on-project-build. I get an error when I try to run pod install
, here is the error: [!] No
Podfile' found in the project directory.`
Thanks for your time.
Hello ,,,
when i try to run the following code :
var scanner: MTBBarcodeScanner
scanner = MTBBarcodeScanner.init(previewView: view_camera)
scanner.didStartScanningBlock = {() -> Void in
print("Start Scanning");
}
scanner.resultBlock = { ( codes:[AnyObject]!) -> Void in
print("Found Code")
}
scanner.startScanning();
Just "Start Scanning" printed and no barcode founded in codes , else i tried many barcode.
Please help me.
Hi mike, thanks for the great work you're doing. I use MTBBarcodeScanner in an universal app, it works like a charm in iPhone but not in iPad sometimes it works sometimes no ...
thanks
If I set torchMode to MTBTorchMode.On before I start scanning, the light turns on briefly, then turns off, then turns back on (i.e. it flickers as it comes on).
If I instead put it in a code block that is delayed by 100 ms so that the code runs AFTER the scanning has started, then it does not flicker on, it just comes on solid (albeit delayed slightly).
I'm assuming this may be related to this PR: #36
But it's not clear to me exactly what is going wrong. Is anyone else seeing this behavior?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.