2.2. Scanning a User-Selected Image

Some applications may need the full resolution offered by camera snapshots, or need to scan an image from the user’s photo library. In these cases you use a ZBarReaderController. This reader is a subclass of UIImagePickerController, and you use it the same way. See the documentation for UIImagePickerController for more detais.

  1. Create the reader.

    This is as simple as creating a new ZBarReaderController:

    ZBarReaderController *reader = [ZBarReaderController new];
    
  2. Setup a delegate to receive the results.

    The delegate should implement the ZBarReaderDelegate protocol, which inherits from UIImagePickerControllerDelegate:

    reader.readerDelegate = self;
    
  3. Configure the reader.

    You will need to set the sourceType appropriately. Aside from the properties of the reader itself, you can configure the decoder via the scanner property:

    if([ZBarReaderController isSourceTypeAvailable:
                                 UIImagePickerControllerSourceTypeCamera])
        reader.sourceType = UIImagePickerControllerSourceTypeCamera;
    [reader.scanner setSymbology: ZBAR_I25
                    config: ZBAR_CFG_ENABLE
                    to: 0];
    

    See Customizing the Interface and Optimizing the Reader for more details.

  4. Present the reader to the user.

    As the reader is a UIImagePickerController, it must be presented modally:

    [self presentModalViewController: reader
          animated: YES];
    
  5. Process the results.

    The controller will call the imagePickerController:didFinishPickingMediaWithInfo: method of your delegate for a successful decode (NB not every time the user takes a picture or selects an image). The barcode data can be obtained using the ZBarReaderControllerResults key of the info dictionary. This key will return “something enumerable”; keep in mind that there may be multiple results. You may also retrieve the corresponding image with UIImagePickerControllerOriginalImage as usual:

    - (void) imagePickerController: (UIImagePickerController*) reader
     didFinishPickingMediaWithInfo: (NSDictionary*) info
    {
        id<NSFastEnumeration> results =
            [info objectForKey: ZBarReaderControllerResults];
        UIImage *image =
            [info objectForKey: UIImagePickerControllerOriginalImage];
        ...
    

    The reader parameter will be the actual ZBarReaderController (again, a subclass UIImagePickerController).

    Note

    The delegate method should dismiss the reader and return as soon as possible; any processing of the results should be deferred until later, otherwise the user will experience unacceptable latency between the actual scan completion and the visual interface feedback.

  6. Dismiss the reader.

    Once you have the results you should dismiss the reader:

    [reader dismissModalViewControllerAnimated: YES];
    

    Warning

    It is very important to dismiss from the reader (not the presenting controller) to avoid corrupting the interface.

2.2.1. Handling Failure

It is always possible the user selects/takes an image that does not contain barcodes, or that the image quality is not sufficient for the ZBar library to scan successfully.

In this case, and if showsHelpOnFail is YES, the integrated help controller will automatically be displayed with reason set to "FAIL".

Your delegate may also choose to implement the optional readerControllerDidFailToRead:withRetry: method to explicitly handle failures. If the retry parameter is NO, you must dismiss the reader before returning, otherwise you may continue and allow the user to retry the operation. Note that, if it is enabled, the integrated help will be displayed when this delegate method is invoked.

Table Of Contents

Previous topic

2.1. Scanning From the Camera Feed

Next topic

2.3. Customizing the Interface