Iphone Snippets‎ > ‎

Use ZBar

First, did you look at "Include library in XCode"  ?

Then, you know you have to rename your .m file in .mm

Choose an image, to do so, let's use the image picker controller :

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        picker.delegate = self;
        picker.allowsImageEditing = true;
        // picker.mediaTypes = [NSArray arrayWithObjects:kUTTypeImage,nil];
        [self presentModalViewController:picker animated:YES];
        [picker release];
       
    }

It will present (in modal mode) the image picker controller.
The user will take the picture and then will be able to zoom/crop to only see the bar code.

As you see, UIImagePickerController's delegate is self so the class 'self' should adopt UIViewControllerDelegate and UIImagePickerControllerDeleagte protocol.
@interface TestZbarViewController : UIViewController <UINavigationControllerDelegate,UIImagePickerControllerDelegate>

Then you should implement two method of UIImagePickerControllerDelegate :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

The first one will be called if the user actually take a picture.
The later is called if the user cancel.

Let's begin with the later, the user really don't want to take a bar code because he need to go to swimming pool:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
}


Before implementing the method that will be called when the user take a picture, the following instructions should be added to your file:
#include "zbar.h"
#include "Magick++.h"
using namespace zbar;
using namespace std;

We need to include zbar and ImageMagick header and we also need to tell XCode we use zbar and std namespace.

And the code you are waiting is:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *pickedImage = [info objectForKey:@"UIImagePickerControllerEditedImage"];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *imgFile = [documentsDirectory stringByAppendingPathComponent:@"tmp.jpg"];
   
    [UIImageJPEGRepresentation(pickedImage, 1.0f) writeToFile:imgFile atomically:YES];
   
    NSLog([NSString stringWithFormat:@"Fichier a charger : '%@'",imgFile]);
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
   
    // create a reader
    ImageScanner scanner;
   
    // configure the reader
    //scanner.set_config(ZEBRA_NONE, ZEBRA_CFG_ENABLE, 1);
   
    // obtain image data
    Magick::Image magick([imgFile cStringUsingEncoding:1]);  // read an image file
    int width = magick.columns();   // extract dimensions
    int height = magick.rows();
    Magick::Blob blob;              // extract the raw data
    magick.modifyImage();
    magick.write(&blob, "GRAY", 8);
    const void *raw = blob.data();
   
    // wrap image data
    Image image(width, height, "Y800", raw, width * height);
   
    // scan the image for barcodes
    scanner.scan(image);
   
    // extract results
    for(Image::SymbolIterator symbol = image.symbol_begin();
        symbol != image.symbol_end();
        ++symbol) {
        // do something useful with results
        printf("decoded %s : %s\n",symbol->get_type_name().c_str(),symbol->get_data().c_str());
        [codeBarre setText:[NSString stringWithCString:symbol->get_data().c_str()]];
    }
   
    // clean up
    image.set_data(NULL, 0);  
}

'codeBarre' is a UILabel to show the user the scanned bar code.

Have fun with ZBar !