简体   繁体   English

Microblink:成功读取一张图片

[英]Microblink: successfully reading an image

I'm asking the Microblink card reader to look at a photo of a card, rather than using the camera.我要求 Microblink 读卡器查看卡片的照片,而不是使用相机。 I've tried both a portrait, and landscape version of a Mastercard.我已经尝试过万事达卡的纵向和横向版本。 This is how I'm declaring my main variables:这就是我声明主要变量的方式:

let blinkCardRecognizer = MBCBlinkCardRecognizer()
var recognizerList = [MBCRecognizer]()

lazy var recognizerCollection: MBCRecognizerCollection = {
    blinkCardRecognizer.extractCvv = false
    blinkCardRecognizer.extractIban = false
    blinkCardRecognizer.extractExpiryDate = false

    recognizerList.append(blinkCardRecognizer)
    return MBCRecognizerCollection(recognizers: recognizerList)
}()
lazy var recognizerRunner: MBCRecognizerRunner = {
    MBCRecognizerRunner(recognizerCollection: recognizerCollection)
}()

I've declared these two delegates:我已经宣布了这两个代表:

MBCBlinkCardOverlayViewControllerDelegate, MBCScanningRecognizerRunnerDelegate

After I get my UIImage, I call this function:在我得到我的 UIImage 后,我称之为 function:

func prepareToReadImage(_ theImage: UIImage?) {
    recognizerRunner.scanningRecognizerRunnerDelegate = self
    
    var image: MBCImage? = nil
    if let anImage = theImage {
        image = MBCImage(uiImage: anImage)
    }
    image?.cameraFrame = true
    image?.orientation = MBCProcessingOrientation.down
    let _serialQueue = DispatchQueue(label: "com.microblink.DirectAPI-sample-swift")
    _serialQueue.async(execute: {() -> Void in
        self.recognizerRunner.processImage(image!)
    })
}

Here is my delegate callback.这是我的委托回调。 Every time, I am getting a status of .empty :每次,我的状态都是.empty

func recognizerRunner(_ recognizerRunner: MBCRecognizerRunner, didFinishScanningWith state: MBCRecognizerResultState) {
    if state == .valid { // values: .empty, .uncertain, .valid, .stageValid
        let result = blinkCardRecognizer.result
        
        DispatchQueue.main.async(execute: {() -> Void in
            print (result.owner)
            print (result.cardNumber)
            print (result.cardNumberPrefix)
        })
    }
}

Any reason why I'm not getting a .valid response?为什么我没有收到.valid回复? Also, does this look like the correct way to be pulling off the card details, once (if and when) I do?此外,这看起来像是提取卡详细信息的正确方法吗,一次(如果以及何时)我这样做? Thanks!谢谢!

Is this issue connected with the issue here ?这个问题与这里的问题有关吗?

If so, I can also suggest the following: You can add a func which calls the image picker (I am using the devices camera as the source type):如果是这样,我还可以提出以下建议:您可以添加一个调用图像选择器的函数(我使用设备相机作为源类型):

private func openImagePicker() {
        let imagePicker = UIImagePickerController()
        imagePicker.sourceType = .camera
        imagePicker.cameraDevice = .rear

        addOverlayLabel(toImagePicker: imagePicker)
        
        // Displays a control that allows the user to choose only photos
        imagePicker.mediaTypes = [kUTTypeImage as String]
        
        // Hides the controls for moving & scaling pictures, or for trimming movies.
        imagePicker.allowsEditing = false
        
        // Shows default camera control overlay over camera preview.
        imagePicker.showsCameraControls = true
        
        // set delegate
        imagePicker.delegate = self
        present(imagePicker, animated: true) {() -> Void in }
        imagePickerController = imagePicker
    }

In the func recognizerRunner , you can place the func to be called when the state is not valid, like this:func recognizerRunner RecognizerRunner 中,您可以放置 state 无效时要调用的 func,如下所示:

extension ViewController: MBCScanningRecognizerRunnerDelegate {

func recognizerRunner(_ recognizerRunner: MBCRecognizerRunner, didFinishScanningWith state: MBCRecognizerResultState) {
    DispatchQueue.main.async(execute: {() -> Void in
        if state != .valid {
            self.openImagePicker()
            return
        }
        
        print(state.rawValue)
        let result = self.blinkCardRecognizer.result

        print("Owner: \(result.owner)")
        print("Card number: \(result.cardNumber)")
        print("Card number prefix: \(result.cardNumberPrefix)")
        
    })
  }
}

This will give you a chance to re-take the image again if the state is not valid.如果 state 无效,这将使您有机会重新拍摄图像。

Also to ask, where are you placing the prepareToReadImage ?还要问,您将prepareToReadImage放在哪里?

You need to place it in the func imagePickerController , like this:您需要将它放在func imagePickerController中,如下所示:

extension ViewController: UIImagePickerControllerDelegate {

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let mediaType = info[UIImagePickerController.InfoKey.mediaType] as? String
    
    if CFStringCompare(mediaType as CFString?, kUTTypeImage, CFStringCompareFlags(rawValue: 9)) == .compareEqualTo {
        let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        prepareToReadImage(originalImage)
    }
    
    picker.dismiss(animated: true, completion: nil)
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    serialQueue.async {
        self.recognizerRunner?.resetState()
    }

    dismiss(animated: true, completion: nil)

  }
}

Lastly, make sure you're placing the settings of the recognizer before starting the scanning process.最后,确保在开始扫描过程之前放置识别器的设置。

I've added the func setupRecognizerRunner , where I'm defining everything you did in your block of code:我添加了func setupRecognizerRunner ,在这里我定义了你在代码块中所做的一切:

    private func setupRecognizerRunner() {

    blinkCardRecognizer = MBCBlinkCardRecognizer()
    var recognizers = [MBCRecognizer]()
    
    blinkCardRecognizer.extractCvv = false
    blinkCardRecognizer.extractIban = false
    blinkCardRecognizer.extractExpiryDate = false
    
    recognizers.append(blinkCardRecognizer)
    let recognizerCollection = MBCRecognizerCollection(recognizers: recognizers)
    recognizerRunner = MBCRecognizerRunner(recognizerCollection: recognizerCollection)
    
    recognizerRunner?.scanningRecognizerRunnerDelegate = self
}

And I've placed it in the viewDidLoad() , after the license key method has been loaded.在加载许可证密钥方法后,我将它放在viewDidLoad()中。

Removing the following line allowed me to get a .valid response:删除以下行使我能够获得.valid响应:

image?.cameraFrame = true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM