本地从 UIImage 扫描条形码(即不使用 ZBar)
Scanning barcode from UIImage natively (i.e., not using ZBar)
自 iOS7 以来,我一直在使用 apple 提供的本机条码扫描器功能,它很棒,但我需要扫描我拥有的一些静态图像,以便自动对一些条码进行分类。
我找不到在本地执行此操作的方法,所以我使用了一个名为 zBar 的开源包,并且在大多数情况下,它工作正常。
但是,它 return 的错误值经常出现,有时甚至无法找到条形码。我还从头开始构建了 c++ 库,但在我的 OS X 构建中得到了相同的结果。这似乎也是一个废弃的项目。
即使我从计算机显示器扫描图像,Apple 的本机解决方案也能找到此静态图像上的条形码! return false/incorrect 值的图像也是如此。
那么有没有办法使用 apple 的库来扫描 UIImage?
试试这个
CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
if (detector) {
NSArray* featuresR = [detector featuresInImage:scannedImg.CIImage];
NSString* decodeR;
for (CIQRCodeFeature* featureR in featuresR) {
NSLog(@"decode %@ ",featureR.messageString);
decodeR = featureR.messageString;
}
}
现在可用的选项是来自 Firebase 的 MLKit。
在他们的控制台中设置您的项目后,将 Firebase 添加到您的项目中 https://firebase.google.com
我使用 cocoapods 来管理依赖项,如果您这样做,请将其添加到您的 Podfile 中 pod update
:
pod 'Firebase/Core'
pod 'Firebase/MLVision'
pod 'Firebase/MLVisionBarcodeModel'
这是一个演示视图控制器实现,您可以在其中从照片库中选择条形码图像以供 ML 套件扫描,并将结果打印在标签中。
// (Don't forget to ask for Photos access by including this in your info.plist)
<key>NSPhotoLibraryUsageDescription</key>
<string>Enable photo library access to select a photo from your library.</string>
import Firebase
class MyDemoViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
lazy var vision = Vision.vision()
@IBOutlet var textLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func selectImage(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
print("Button capture")
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .savedPhotosAlbum;
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
return
}
dismiss(animated: true, completion: {
self.checkForCodeInImage(image: image)
})
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion:nil)
}
internal func checkForCodeInImage(image: UIImage) {
let detector = vision.barcodeDetector(options: VisionBarcodeDetectorOptions(formats: .all))
let vImage = VisionImage(image: image)
detector.detect(in: vImage) { features, error in
guard error == nil, let barcodes = features, barcodes.isEmpty == false else {
DispatchQueue.main.async {
self.textLabel.text = "No code found in selected image."
}
return
}
var text = ""
for barcode in barcodes {
guard let rawValue = barcode.rawValue else {
continue
}
let corners = barcode.cornerPoints
let displayValue = barcode.displayValue
print("Corners: \(String(describing: corners))")
print("Found: \(String(describing: displayValue))")
text.append(rawValue)
text.append("\n\n")
// let valueType = barcode.valueType
// switch valueType {
// case .wiFi:
// let ssid = barcode.wifi!.ssid
// let password = barcode.wifi!.password
// let encryptionType = barcode.wifi!.type
// case .URL:
// let title = barcode.url!.title
// let url = barcode.url!.url
// default:
// // See API reference for all supported value types
// break
// }
}
DispatchQueue.main.async {
self.textLabel.text = text
}
}
}
}
这是他们文档的 link:https://firebase.google.com/docs/ml-kit/ios/read-barcodes
自 iOS7 以来,我一直在使用 apple 提供的本机条码扫描器功能,它很棒,但我需要扫描我拥有的一些静态图像,以便自动对一些条码进行分类。
我找不到在本地执行此操作的方法,所以我使用了一个名为 zBar 的开源包,并且在大多数情况下,它工作正常。
但是,它 return 的错误值经常出现,有时甚至无法找到条形码。我还从头开始构建了 c++ 库,但在我的 OS X 构建中得到了相同的结果。这似乎也是一个废弃的项目。
即使我从计算机显示器扫描图像,Apple 的本机解决方案也能找到此静态图像上的条形码! return false/incorrect 值的图像也是如此。
那么有没有办法使用 apple 的库来扫描 UIImage?
试试这个
CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
if (detector) {
NSArray* featuresR = [detector featuresInImage:scannedImg.CIImage];
NSString* decodeR;
for (CIQRCodeFeature* featureR in featuresR) {
NSLog(@"decode %@ ",featureR.messageString);
decodeR = featureR.messageString;
}
}
现在可用的选项是来自 Firebase 的 MLKit。
在他们的控制台中设置您的项目后,将 Firebase 添加到您的项目中 https://firebase.google.com
我使用 cocoapods 来管理依赖项,如果您这样做,请将其添加到您的 Podfile 中 pod update
:
pod 'Firebase/Core'
pod 'Firebase/MLVision'
pod 'Firebase/MLVisionBarcodeModel'
这是一个演示视图控制器实现,您可以在其中从照片库中选择条形码图像以供 ML 套件扫描,并将结果打印在标签中。
// (Don't forget to ask for Photos access by including this in your info.plist)
<key>NSPhotoLibraryUsageDescription</key>
<string>Enable photo library access to select a photo from your library.</string>
import Firebase
class MyDemoViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
lazy var vision = Vision.vision()
@IBOutlet var textLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func selectImage(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
print("Button capture")
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .savedPhotosAlbum;
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
return
}
dismiss(animated: true, completion: {
self.checkForCodeInImage(image: image)
})
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion:nil)
}
internal func checkForCodeInImage(image: UIImage) {
let detector = vision.barcodeDetector(options: VisionBarcodeDetectorOptions(formats: .all))
let vImage = VisionImage(image: image)
detector.detect(in: vImage) { features, error in
guard error == nil, let barcodes = features, barcodes.isEmpty == false else {
DispatchQueue.main.async {
self.textLabel.text = "No code found in selected image."
}
return
}
var text = ""
for barcode in barcodes {
guard let rawValue = barcode.rawValue else {
continue
}
let corners = barcode.cornerPoints
let displayValue = barcode.displayValue
print("Corners: \(String(describing: corners))")
print("Found: \(String(describing: displayValue))")
text.append(rawValue)
text.append("\n\n")
// let valueType = barcode.valueType
// switch valueType {
// case .wiFi:
// let ssid = barcode.wifi!.ssid
// let password = barcode.wifi!.password
// let encryptionType = barcode.wifi!.type
// case .URL:
// let title = barcode.url!.title
// let url = barcode.url!.url
// default:
// // See API reference for all supported value types
// break
// }
}
DispatchQueue.main.async {
self.textLabel.text = text
}
}
}
}
这是他们文档的 link:https://firebase.google.com/docs/ml-kit/ios/read-barcodes