diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 00:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 00:06:44 +0000 |
commit | 44cf8ec67278bd1ab6c7f83a9993f7a5686a9541 (patch) | |
tree | 5eec4b0d1a3f163d279c3c27c03324ba49fa235a /iphone/doc | |
parent | Initial commit. (diff) | |
download | zbar-44cf8ec67278bd1ab6c7f83a9993f7a5686a9541.tar.xz zbar-44cf8ec67278bd1ab6c7f83a9993f7a5686a9541.zip |
Adding upstream version 0.23.93.upstream/0.23.93upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'iphone/doc')
26 files changed, 2836 insertions, 0 deletions
diff --git a/iphone/doc/Documentation.html b/iphone/doc/Documentation.html new file mode 100644 index 0000000..c6a532a --- /dev/null +++ b/iphone/doc/Documentation.html @@ -0,0 +1,11 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> +<meta http-equiv="Refresh" content="0; url=Documentation/index.html"/> +</head> +<body> +<p>redirecting to <a href="Documentation/index.html">Documentation/index.html</a></p> +</body> +</html> diff --git a/iphone/doc/ZBarImage.rst b/iphone/doc/ZBarImage.rst new file mode 100644 index 0000000..59f537e --- /dev/null +++ b/iphone/doc/ZBarImage.rst @@ -0,0 +1,150 @@ +ZBarImage Class Reference +========================= + +.. class:: ZBarImage + + :Inherits from: :class:`NSObject` + + A :class:`ZBarImage` is a wrapper for images passed to the barcode reader. + It encapsulates raw image data with the format and size metadata necessary + to interpret it. + + An image must be wrapped in a :class:`ZBarImage` in order to be scanned by + the library. At least the format, size and data must be set. There are + also initialization methods for automatically extracting the data and + format from a `CGImage`. + + This class is a wrapper around a :type:`zbar_image_t` C object (q.v.) + + +Properties +---------- + + .. member:: unsigned long format + + The image format four-charcter code (fourcc) as a 4-byte integer. Use + :ref:`fourcc:<fourcc:>` to create a fourcc value from a string. + + .. member:: unsigned sequence + + A "sequence number" associated with the image. This reference value is + unused by the library. + + .. member:: CGSize size + + The size of the image in pixels. + + .. note:: + + There is no separate "bytesPerLine" property, the width must match + the image data (which is not always the logical image width). + + .. member:: CGRect crop + + Optionally limit the scan region to this rectangle without having to + generate a cropped image. + + .. member:: const void *data + + Obtain a pointer to the raw image data. This property is read-only, use + :ref:`setData:withLength:<setData:withLength:>` to set the image data. + + .. member:: unsigned long dataLength + + Byte length of the raw image data. This property is read-only, use + :ref:`setData:withLength:<setData:withLength:>` to set the image data. + + .. member:: ZBarSymbolSet *symbols + + Barcode results from the last scan. + + .. member:: zbar_image_t *zbarImage + + Retrieve the underlying C object instance. (read-only) + + .. member:: UIImage *UIImage + + Convert the image to a UIImage. Only certain image formats are + supported for conversion (read-only) + + :See also: :ref:`UIImageWithOrientation:<UIImageWithOrientation:>` + + +Class Methods +------------- + + .. _`fourcc:`: + .. describe:: + (unsigned long) fourcc:(NSString*)format + + Parse the integer four-character code from a string. Alternatively use + the :func:`zbar_fourcc` macro to create a constant expression. + + :format: A four character string representing an image format. + :Returns: The corresponding 4-byte integer format code. + + +Instance Methods +---------------- + + .. _`initWithImage:`: + .. describe:: - (id) initWithImage:(zbar_image_t*)image + + Initialize an image wrapper, given the C object to wrap. + + :image: The C object to wrap. + :Returns: The initialized :class:`ZBarImage`. + + .. _`initWithCGImage:`: + .. describe:: - (id) initWithCGImage:(CGImageRef)image + + Initialize a :class:`ZBarImage` from the data and metadata extracted + from a `CGImage`. The image is converted to `Y800` (grayscale) format. + + :image: A `CGImage` to source the data and metadata. + :Returns: The initialized :class:`ZBarImage`. + :See also: :ref:`initWithCGImage:size:<initWithCGImage:size:>` + + .. _`initWithCGImage:size:`: + .. describe:: - (id) initWithCGImage:(CGImageRef)image size:(CGSize)size + + Initialize a :class:`ZBarImage` from the data and metadata extracted + from a `CGImage`. The image is converted to `Y800` (grayscale) format + and scaled to the specified size. + + :image: A `CGImage` to source the data and metadata. + :size: The pixel size of the resulting ZBarImage. + :Returns: The initialized :class:`ZBarImage`. + :See also: :ref:`initWithCGImage:crop:size:<initWithCGImage:crop:size:>` + + .. _`initWithCGImage:crop:size:`: + .. describe:: - (id) initWithCGImage:(CGImageRef)image crop:(CGRect)crop size:(CGSize)size + + Initialize a :class:`ZBarImage` from the data and metadata extracted + from a `CGImage`. The image is simultaneously converted to `Y800` + (grayscale) format, cropped and scaled to the specified size. + + :image: A `CGImage` to source the data and metadata. + :crop: The region to convert, in image coordinates. + :size: The pixel size of the resulting ZBarImage. + :Returns: The initialized :class:`ZBarImage`. + + .. _`setData:withLength:`: + .. describe:: - (void) setData:(const void*)data withLength:(unsigned long)length + + Specify a pointer to the raw image data, for the image format and size. + The length of the data must also be provided. Note that the data must + remain valid as long as the image has a reference to it. Set data to + ``NULL`` to clear a previous reference. + + :data: A pointer to a raw image data buffer. + :length: The size of the image data buffer. + + .. _`UIImageWithOrientation:`: + .. describe:: - (UIImage*) UIImageWithOrientation:(UIImageOrientation)orient + + Convert the image to a UIImage with the specified orientation. Only + certain image formats are supported for conversion. (currently + ``RGB3``, ``RGB4``, ``RGBQ``) + + :orient: Desired orientation of the image. + :Returns: A new :class:`UIImage`, or ``nil`` in case of error. diff --git a/iphone/doc/ZBarImageScanner.rst b/iphone/doc/ZBarImageScanner.rst new file mode 100644 index 0000000..5835a17 --- /dev/null +++ b/iphone/doc/ZBarImageScanner.rst @@ -0,0 +1,99 @@ +ZBarImageScanner Class Reference +================================ + +.. class:: ZBarImageScanner + + :Inherits from: :class:`NSObject` + + This is a low-level interface for programmatically scanning images without + a user interface. If you want to scan images manually selected by the user + (from the photo library or using the camera), you may prefer to use a + :class:`ZBarReaderController` instead. + + This class is a wrapper around a :type:`zbar_image_scanner_t` C object + (q.v.) + + +Properties +---------- + + .. member:: BOOL enableCache + + Enable the inter-frame consistency cache. Set to ``YES`` for scanning + video or ``NO`` for scanning images. + + .. member:: ZBarSymbolSet results + + Decoded symbols resulting from the last scan. + + +Instance Methods +---------------- + + .. _`parseConfig:`: + .. describe:: - (void) parseConfig:(NSString*)config + + Apply scanner/decoder configuration parsed from a string. + + :config: A configuration setting of the form: `symbology.config[=value]`. + + .. _`setSymbology:config:to:`: + .. describe:: - (void) setSymbology:(zbar_symbol_type_t)symbology config:(zbar_config_t)config to:(int)value + + Apply generic scanner/decoder configuration. + + :symbology: The symbology to effect, or 0 for all. + :config: The configuration setting to adjust. + :value: The value to set for the specific configuration/symbology. + + .. _`scanImage:`: + .. describe:: - (NSInteger) scanImage:(ZBarImage*)image + + Scan an image for barcodes using the current configuration. The image + must be in ``Y800`` format (8-bpp graysale). + + :image: The :class:`ZBarImage` to scan. + :Returns: The number of barcode symbols decoded in the image. + + +Constants +--------- + +.. type:: zbar_config_t + + ZBAR_CFG_ENABLE + Control whether specific symbologies will be recognized. Disabling + unused symbologies improves performance and prevents bad scans. + + ZBAR_CFG_EMIT_CHECK + Whether to include the check digit in the result data string. This + value may be set individually for symbologies where it makes sense. + + ZBAR_CFG_MIN_LEN + The minimum data length for a symbol to be valid, set to 0 to disable. + Use with eg, I2/5 to avoid short scans. This value may be set + individually for variable-length symbologies. + + ZBAR_CFG_MAX_LEN + The maximum data length for which a symbol is valid, set to 0 to + disable. Use with eg, I2/5 to enforce a specific range of data lengths. + This value may be set individually for variable-length symbologies. + + ZBAR_CFG_UNCERTAINTY + Number of "nearby" frames that must contain a symbol before it will be + considered valid. This value may be set for individual symbologies. + + ZBAR_CFG_POSITION + Whether to track position information. + + ZBAR_CFG_X_DENSITY + The stride to use for scanning vertical columns of the image. This many + pixel columns will be skipped between vertical scan passes. Useful for + trading off between resolution and performance. This is a scanner + setting (use 0 for the symbology). + + ZBAR_CFG_Y_DENSITY + The stride to use for scanning horizontal columns of the image. This + many pixel rows will be skipped between horizontal scan passes. Useful + for trading off between resolution and performance. This is a scanner + setting (use 0 for the symbology). diff --git a/iphone/doc/ZBarReaderController.rst b/iphone/doc/ZBarReaderController.rst new file mode 100644 index 0000000..cf7ee09 --- /dev/null +++ b/iphone/doc/ZBarReaderController.rst @@ -0,0 +1,156 @@ +ZBarReaderController Class Reference +==================================== + +.. class:: ZBarReaderController + + :Inherits from: :class:`UIImagePickerController` + + This is the controller to use for scanning images selected by a + :class:`UIImagePickerController` either captured manually using the camera, + or selected from the Photo Library. For more information, see + :doc:`picker`. + + It can support automatic capture from the camera only if the library is + re-built to use private APIs (see :doc:`compat`). + + +Properties +---------- + + .. member:: ZBarImageScanner *scanner + + Access to the image scanner for configuration. (read-only) + + .. member:: id<ZBarReaderDelegate> readerDelegate + + The delegate that will be notified when new barcode results are + available. + + .. member:: BOOL showsZBarControls + + Whether to display a default control set consisting of cancel, scan and + info buttons. Disable these if you provide your own controls using the + :member:`cameraOverlayView`. Enabling this automatically disables the + system controls :member:`showsCameraControls`. (Default ``YES``). + + .. member:: BOOL showsHelpOnFail + + Whether to automatically display the integrated help viewer when an + image fails to decode. Even if this is disabled, the integrated help + may still be presented manually using ``showHelpWithReason:``. + (Default ``YES``) + + .. member:: ZBarReaderControllerCameraMode cameraMode + + Scanning mode to use with the camera. It is generally appropriate to + leave this at the default. + + .. member:: BOOL tracksSymbols + + Whether to display the tracking rectangle around detected barcodes. + + .. member:: BOOL takesPicture + + Whether to take a full picture (with ``takePicture``) when a barcode + is detected with ``ZBarReaderControllerCameraModeSampling``. The + resulting image will be delayed from the actual decode. + + .. member:: BOOL enableCache + + This property is deprecated and should not be modified. + + .. member:: CGRect scanCrop + + Crop images before scanning. The original image will be cropped to this + rectangle, which should be in normalized image coordinates, x-axis + major. Defaults to the full image ``{{0, 0}, {1, 1}}``. + + .. member:: NSInteger maxScanDimension + + Scale image to scan. After cropping, the image will be scaled if + necessary, such that neither of its dimensions exceed this value. + Defaults to 640. + + .. note:: + + The remaining properties are inherited from + :class:`UIImagePickerController`. + + .. member:: UIImagePickerControllerSourceType sourceType + + Image source. Use to select between the camera and photo library. + + .. member:: BOOL showsCameraControls + + Whether to display the system camera controls. Overridden to ``NO`` + when :member:`showsZBarControls` is ``YES``. + + .. member:: UIView *cameraOverlayView + + A custom view to display over the camera preview. The tracking layer + and default controls will be added to this view if they are enabled. + + .. member:: CGAffineTransform cameraViewTransform + + A transform to apply to the camera preview. Ignored by the reader. + Possibly useful for eg, a digital zoom effect. + + .. member:: BOOL allowsEditing + + Whether to enable the system image editing dialog after a picture is + taken. Possibly useful to improve reader results in some cases using + manual intervention. + + +Instance Methods +---------------- + + .. _`showHelpWithReason:`: + .. describe:: - (void) showHelpWithReason:(NSString*)reason + + Display the integrated help browser. Use this with custom overlays if + you don't also want to create your own help view. Should only be called + when the reader is displayed. The ``reason`` argument will be passed to + the :func:`onZBarHelp` javascript function. + + :reason: A string parameter passed to javascript. + + .. _`scanImage:`: + .. describe:: - (id <NSFastEnumeration>) scanImage:(CGImageRef)image + + Scan an image for barcodes. This is a wrapper around + ``scanner.scanImage`` that applies scanCrop and maxScanDimension. Some + additional result filtering is also performed. + + :image: A :class:`CGImage` to scan. + :Returns: The result set containing :class:`ZBarSymbol` objects. + + +Constants +--------- + +.. type:: ZBarReaderControllerCameraMode + + The scanning mode to use with the camera. + + ZBarReaderControllerCameraModeDefault + The standard mode provided by UIImagePickerController - the user + manually captures an image by tapping a control. This is the default + unless private APIs are enabled. + + ZBarReaderControllerCameraModeSampling + Automatically capture by taking screenshots with + :func:`UIGetScreenImage`. Resolution is limited to the screen + resolution, so this mode is inappropriate for longer codes. Only + available when private APIs are enabled, and becomes the default mode in + that case. + + ZBarReaderControllerCameraModeSequence + Experimental mode that automatically scans by "rapidly" scanning + pictures captured with ``takePicture``. Not recommended for serious + use. + +.. c:var:: NSString *ZBarReaderControllerResults + + The info dictionary key used to return decode results to + ``imagePickerController:didFinishPickingMediaWithInfo:`` diff --git a/iphone/doc/ZBarReaderDelegate.rst b/iphone/doc/ZBarReaderDelegate.rst new file mode 100644 index 0000000..34b52c7 --- /dev/null +++ b/iphone/doc/ZBarReaderDelegate.rst @@ -0,0 +1,70 @@ +ZBarReaderDelegate Protocol Reference +===================================== + +.. class:: ZBarReaderDelegate + + :Inherits from: :class:`UIImagePickerControllerDelegate` + + This protocol must be implemented by the + :member:`~ZBarReaderViewController::readerDelegate` provided to a + :class:`ZBarReaderViewController` or :class:`ZBarReaderController`. It is + used to notify the delegate of new decode results, when an image fails to + decode, or when the user dismisses the reader with the built-in controls. + + +Instance Methods +---------------- + + .. describe:: - (void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info + + This inherited delegate method is called when a barcode is successfully + decoded. The decoded symbols are available from the dictionary as a + :class:`ZBarSymbolSet` using the :c:data:`ZBarReaderControllerResults` + key. The image from which the barcodes were scanned is available using + the :c:data:`UIImagePickerControllerOriginalImage` key. No other keys + are guaranteed to be valid. + + .. note:: + + The ``picker`` parameter will be the reader controller instance that + read the barcodes - not necessarily a + :class:`UIImagePickerController` instance. You should cast it to the + correct type for anything other than basic view controller access. + + :picker: The reader controller that scanned the barcode(s). + :info: A dictionary containing the image and decode results. + + .. describe:: - (void) imagePickerControllerDidCancel:(UIImagePickerController*)picker + + Called when the user taps the "Cancel" button provided by the built-in + controls (when :member:`showsZBarControls`\ ``=YES``). The default + implementation dismisses the reader. If this method is implemented, it + should do the same. + + .. note:: + + The ``picker`` parameter will be the reader controller instance that + read the barcodes - not necessarily a + :class:`UIImagePickerController` instance. You should cast it to the + correct type for anything other than basic view controller access. + + :picker: The reader controller that scanned the barcode(s). + + .. describe:: - (void) readerControllerDidFailToRead:(ZBarReaderController*)reader withRetry:(BOOL)retry + + Called when an image, manually captured or selected from the photo + library, is scanned and no barcodes were detected. + + If the ``retry`` parameter is ``NO``, the controller must be dismissed + before this method returns. Otherwise, another scan may be attempted + without re-presenting the controller. + + If the :member:`~ZBarReaderController::showsHelpOnFail` is ``YES`` *and* + ``retry`` is ``YES``, the integrated help viewer will already be + presenting. + + If this method is not implemented, the controller will be dismissed iff + ``retry`` is ``NO``. + + :reader: The :class:`ZBarReaderController` that scanned the barcode(s). + :retry: Whether another scan may be attempted. diff --git a/iphone/doc/ZBarReaderView.rst b/iphone/doc/ZBarReaderView.rst new file mode 100644 index 0000000..d434215 --- /dev/null +++ b/iphone/doc/ZBarReaderView.rst @@ -0,0 +1,126 @@ +ZBarReaderView Class Reference +============================== + +.. class:: ZBarReaderView + + :Inherits from: :class:`UIView` + + This is a barcode reader encapsulted in a UIView. It manages an + :class:`AVCaptureSession` with a camera device and a + :class:`ZBarCaptureReader`, presents the video preview and optionally + tracks detected barcode symbols. A delegate will usually be assigned for + notification of new decode results. + + +Properties +---------- + + .. member:: id<ZBarReaderViewDelegate> readerDelegate + + The delegate that will be notified of new decode results. + + .. member:: ZBarImageScanner *scanner + + Access to the image scanner is provided for configuration. (read-only) + + .. member:: BOOL tracksSymbols + + Whether to display the tracking annotation (default ``YES``). + + .. member:: UIColor *trackingColor + + The color of the tracking annotation (default green). + + .. member:: BOOL allowsPinchZoom + + Enable pinch gesture recognition for manually zooming the preview/decode + (default ``YES``). + + .. member:: NSInteger torchMode + + An :type:`AVCaptureTorchMode` value that will be applied if/when + appropriate. (default Auto) + + .. member:: BOOL showsFPS + + Overlay the decode frame rate on the preview to help with performance + optimization. This is for *debug only* and should not be set for + production. (default ``NO``) + + .. member:: CGFloat zoom + + Zoom scale factor applied to the video preview *and* scanCrop. This + value is also updated by the pinch-zoom gesture. Valid values are in + the range [1,maxZoom]. (default 1.25) + + .. member:: CGFloat maxZoom + + Maximum settable zoom level. The zoom property will be clipped to this + value. + + .. member:: CGRect scanCrop + + The region of the video image that will be scanned, in normalized image + coordinates. Note that the video image is in landscape mode (default + {{0, 0}, {1, 1}}) + + .. member:: CGAffineTransform previewTransform + + Additional transform that will be applied to the video preview. Note + that this transform is *not* applied to scanCrop. + + .. member:: AVCaptureDevice *device + + The capture device may be manipulated or replaced. + + .. member:: AVCaptureSession *session + + Direct access to the capture session. Warranty void if opened. + (read-only) + + .. member:: ZBarCaptureReader *captureReader + + Direct access to the capture reader. Warranty void if opened. + (read-only) + + .. member:: BOOL enableCache + + :Deprecated: + + Whether to use the inter-frame consistency cache. This should always be + set to ``YES``. + + +Instance Methods +---------------- + + .. describe:: - (id) initWithImageScanner:(ZBarImageScanner*)imageScanner + + :imageScanner: A pre-configured :class:`ZBarImageScanner` to use for scanning + :Returns: The initialized :class:`ZBarReaderView` + + .. describe:: - (void) start + + Begin/resume scanning after a call to ``stop``. + + .. describe:: - (void) stop + + Stop scanning and pause the video feed. + + .. describe:: - (void) flushCache + + Flush the inter-frame consistency cache. Any barcodes in the frame will + be re-recognized in subsequent frames. + + .. _`setZoom:animated:`: + .. describe:: - (void) setZoom:(CGFloat)zoom animated:(BOOL)animated + + Set the zoom property with optional animation. + + .. _`willRotateTointerfaceOrientation:duration:`: + .. describe:: - (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration + + Compensate for device / camera / interface orientation. Must be called + by containing view controller that supports any non-portrait orientation + to restore the camera preview to the correct orientation. Call from + view controller method of the same name for correct animation. diff --git a/iphone/doc/ZBarReaderViewController.rst b/iphone/doc/ZBarReaderViewController.rst new file mode 100644 index 0000000..4366079 --- /dev/null +++ b/iphone/doc/ZBarReaderViewController.rst @@ -0,0 +1,190 @@ +ZBarReaderViewController Class Reference +======================================== + +.. class:: ZBarReaderViewController + + :Inherits from: :class:`UIViewController` + + This is the controller to use for live scanning from the camera feed with + automatic capture. For scanning from image files or with manual capture, + see :class:`ZBarReaderController`. + + +Properties +---------- + + .. member:: ZBarImageScanner *scanner + + Access to the image scanner for configuration. (read-only) + + .. member:: id <ZBarReaderDelegate> readerDelegate + + The delegate that will be notified when new barcode results are + available. + + .. member:: BOOL showsZBarControls + + Whether to display a default control set consisting of cancel, scan and + info buttons. Disable these if you provide your own controls using the + :member:`cameraOverlayView`. (Default ``YES``). + + .. member:: BOOL tracksSymbols + + Whether to display the tracking rectangle around detected barcodes. + + .. member:: NSUInteger supportedOrientationsMask + + Set of interface orientations that the controller should support. Use + :func:`ZBarOrientationMask` or ``ZBarOrientationMaskAll`` to + generate the mask. + + .. member:: CGRect scanCrop + + Crop images before scanning. The original image will be cropped to this + rectangle, which should be in normalized image coordinates (NB the + camera image x-axis is *vertical* on the screen). Defaults to the full + image ``{{0, 0}, {1, 1}}``. + + .. member:: UIView *cameraOverlayView + + A custom view to display over the camera preview. + + .. member:: CGAffineTransform cameraViewTransform + + A transform to apply to the camera preview. Ignored by the reader. + + .. member:: UIImagePickerControllerCameraDevice cameraDevice + + The camera device to use for scanning. Defaults to the system default + camera. + + .. member:: UIImagePickerControllerCameraFlashMode cameraFlashMode + + The "flash" (aka torch) mode to use while scanning. Defaults to + UIImagePickerControllerCameraFlashModeAuto. + + .. member:: UIImagePickerControllerQualityType videoQuality + + The resolution to use while scanning. Defaults to + UIImagePickerControllerQuality640x480. + + .. member:: ZBarReaderView *readerView + + View that presents the camera preview and performs the scanning. This + view has other properties you may use to control the appearance and + behavior of the reader. + + Note that this view may be released when it is not displayed (eg, under + low memory conditions). You should apply any configuration just before + you present the reader. + + .. member:: BOOL enableCache + + This property is deprecated and should not be modified. + + .. warning:: + + The remaining properties are deprecated, they are only present for + backward compatibility with :class:`ZBarReaderController` and will raise + an exception if inappropriate/unsupported values are set. + + .. member:: UIImagePickerControllerSourceType sourceType + + Raises an exception if anything other than + ``UIImagePickerControllerSourceTypeCamera`` is set. If you want to scan + images, use a :class:`ZBarReaderController` instead of this class. + + .. member:: UIImagePickerControllerCameraCaptureMode cameraCaptureMode + + Raises an exception if anything other than + ``UIImagePickerControllerCameraCaptureModeVideo`` is set. + + .. member:: BOOL allowsEditing + + Raises an exception if anything other than ``NO`` is set. + + .. member:: BOOL showsCameraControls + + Raises an exception if anything other than ``NO`` is set. Use + :member:`showsZBarControls` to disable the buit-in overlay. + + .. member:: BOOL showsHelpOnFail + + Any value set to this property is ignored. It is only useful for + scanning images, for which you should use :class:`ZBarReaderController`. + + .. member:: ZBarReaderControllerCameraMode cameraMode + + This reader only supports scanning from the camera feed. If you want to + scan manually captured images, use a :class:`ZBarReaderController` + instead of this class. + + .. member:: BOOL takesPicture + + Raises an exception if anything other than ``NO`` is set. This + controller automatically returns the scanned camera frame and does not + support capturing a separate image. + + .. member:: NSInteger maxScanDimension + + Any value set to this property is ignored. It is only useful for + scanning images, for which you should use :class:`ZBarReaderController`. + + +Class Methods +------------- + + .. describe:: + (BOOL) isSourceTypeAvailable:(UIImagePickerControllerSourceType)source + + Returns ``YES`` only if ``source`` is ``Camera`` and the + :class:`UImagePickerController` method of the same name also returns + ``YES``. + + .. describe:: + (BOOL) isCameraDeviceAvailable:(UIImagePickerControllerCameraDevice)cameraDevice + + See the :class:`UImagePickerController` method of the same name. + + .. describe:: + (BOOL) isFlashAvailableForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice + + See the :class:`UImagePickerController` method of the same name. + + .. describe:: + (NSArray*) availableCaptureModesForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice + + Returns an array with the single element + ``UIImagePickerControllerCameraCaptureModeVideo`` if the device is + available, otherwise returns an empty array. + + +Instance Methods +---------------- + + .. _`showHelpWithReason:`: + .. describe:: - (void) showHelpWithReason:(NSString*)reason + + Display the integrated help browser. Use this with custom overlays if + you don't also want to create your own help view. Should only be called + when the reader is displayed. The ``reason`` argument will be passed to + the :func:`onZBarHelp` javascript function. + + :reason: A string parameter passed to javascript. + + .. _`takePicture`: + .. describe:: - (void) takePicture + + Capture the next available frame and send it over the usual delegate + path. + + +Macros +------ + + .. function:: ZBarOrientationMask(interfaceOrientation) + + Generate a bit-mask for the specified interface orientation, suitable + for setting :member:`supportedOrientationsMask`. + + .. describe:: ZBarOrientationMaskAll + + Combination of :func:`ZBarOrientationMask` for all interface + orientations (Portrait, PortraitUpsideDown, LandscapeLeft and + LandscapeRight) diff --git a/iphone/doc/ZBarReaderViewDelegate.rst b/iphone/doc/ZBarReaderViewDelegate.rst new file mode 100644 index 0000000..e6730cb --- /dev/null +++ b/iphone/doc/ZBarReaderViewDelegate.rst @@ -0,0 +1,26 @@ +ZBarReaderViewDelegate Protocol Reference +========================================= + +.. class:: ZBarReaderViewDelegate + + :Inherits from: :class:`NSObject` + + This protocol, which must be implemented by the `readerDelegate` provided + to a :class:`ZBarReaderView`, is used to notify the delegate of new decode + results. + + +Instance Methods +---------------- + + .. describe:: - (void) readerView:(ZBarReaderView*)readerView didReadSymbols:(ZBarSymbolSet*)symbols fromImage:(UIImage*)image + + Called to notify the delegate of new decode results. + + Note that the referenced image is a proxy for a video buffer that is + asynchronously being converted to a :class:`UIImage`, attempting to + access the data will block until the conversion is complete. + + :readerView: :class:`ZBarReaderView` that scanned the barcode(s). + :symbols: :class:`ZBarSymbolSet` containing the decode results. + :image: :class:`UIImage` from which the barcode(s) were scanned. diff --git a/iphone/doc/ZBarSymbol.rst b/iphone/doc/ZBarSymbol.rst new file mode 100644 index 0000000..058a7b1 --- /dev/null +++ b/iphone/doc/ZBarSymbol.rst @@ -0,0 +1,186 @@ +ZBarSymbol Class Reference +========================== + +.. class:: ZBarSymbol + + :Inherits from: :class:`NSObject` + + A symbol wraps all of the information the library has about a decoded + barcode. Use the available properties to retrieve the barcode data, the + symbology (type of barcode), location and more. + + This class is a simple wrapper around a :type:`zbar_symbol_t` C object + (q.v.) + + +Properties +---------- + + .. member:: zbar_symbol_type_t type + + The type of symbology that was decoded. (read-only) + + .. member:: NSString *typeName + + The canonical name used by the library to represent the symbology. + (read-only) + + .. member:: NSUInteger configMask + + Bitmask of symbology config settings used during decode. + + .. member:: NSUInteger modifierMask + + Bitmask of symbology characteristics detected during decode. See + :type:`zbar_modifier_t` for the currently defined modifier bits. + + .. member:: NSString *data + + The raw decoded barcode data. (read-only) + + .. member:: int quality + + A relative metric indicating rough confidence in the decoded value. + Larger values are better than smaller values. (read-only) + + .. member:: zbar_orientation_t orientation + + The general, axis-aligned orientation of the symbol, or + ZBAR_ORIENT_UNKNOWN if unknown. (read-only) + + .. member:: ZBarSymbolSet *components + + The components of a composite symbol. (read-only) + + .. member:: const zbar_symbol_t *zbarSymbol + + Retrieve the underlying C object instance. (read-only) + + .. member:: CGRect bounds + + Calculate a rough bounding box for the symbol. (read-only) + + .. note:: + + Coordinates are relative to the image *data*, which may not match a + displayed UIImage. Make sure to account for the UIImage orientation + when using these values. + + +Class Methods +------------- + + .. _`nameForType:`: + .. describe:: + (NSString*) nameForType:(zbar_symbol_type_t)type + + Retrieve the canonical name for a symbology used by the library, given + its enumerated value. + + :type: The :type:`zbar_symbol_type_t` enumerated symbology value. + :Returns: A short string name for the symbology. + + +Instance Methods +---------------- + + .. _`initWithSymbol:`: + .. describe:: - (id) initWithSymbol:(const zbar_symbol_t*)symbol + + Initialize a symbol wrapper, given the C object to wrap. + + :symbol: The C object to wrap. + :Returns: The initialized symbol, or nil if an error occurred. + + +Constants +--------- + +.. type:: zbar_symbol_type_t + + Symbology identifiers. + + ZBAR_NONE + No symbol was decoded. + + ZBAR_PARTIAL + Intermediate status. + + ZBAR_EAN8 + EAN-8 + + ZBAR_UPCE + UPC-E + + ZBAR_ISBN10 + ISBN-10, converted from EAN-13 + + ZBAR_UPCA + UPC-A + + ZBAR_EAN13 + EAN-13 + + ZBAR_ISBN13 + ISBN-13, converted from EAN-13 + + ZBAR_I25 + Interleaved 2 of 5 + + ZBAR_DATABAR + GS1 DataBar (RSS) + + ZBAR_DATABAR_EXP + GS1 DataBar Expanded + + ZBAR_CODABAR + Codabar + + ZBAR_CODE39 + Code 39 (3 of 9) + + ZBAR_QRCODE + QR Code + + ZBAR_CODE128 + Code 128 + +.. type:: zbar_orientation_t + + The coarse orientation of a symbol. + + .. note:: + + Orientation is relative to the image *data*, which may not match a + displayed UIImage. Make sure to account for the UIImage orientation + when using these values. + + ZBAR_ORIENT_UNKNOWN + Unable to determine orientation. + + ZBAR_ORIENT_UP + Upright, read left to right + + ZBAR_ORIENT_RIGHT + Sideways, read top to bottom + + ZBAR_ORIENT_DOWN + Upside-down, read right to left + + ZBAR_ORIENT_LEFT + Sideways, read bottom to top + +.. type:: zbar_modifier_t + + Decoder symbology modifier flags. + + .. note:: + + These are bit indices, use eg, (1 << ZBAR_MOD_GS1) to test the + modifierMask property. + + ZBAR_MOD_GS1 + Barcode tagged as GS1 (EAN.UCC) reserved (eg, FNC1 before first data + character). Data may be parsed as a sequence of GS1 AIs. + + ZBAR_MOD_AIM + Barcode tagged as AIM reserved. diff --git a/iphone/doc/ZBarSymbolSet.rst b/iphone/doc/ZBarSymbolSet.rst new file mode 100644 index 0000000..7983869 --- /dev/null +++ b/iphone/doc/ZBarSymbolSet.rst @@ -0,0 +1,43 @@ +ZBarSymbolSet Class Reference +============================= + +.. class:: ZBarSymbolSet + + :Inherits from: :class:`NSObject` + :Conforms to: :class:`NSFastEnumeration` + + A symbol set is a simple container for the symbols scanned from an image. + It supports :class:`NSFastEnumeration`, and not much else... Use it to + iterate through the :class:`ZBarSymbol` objects in a decode result set:: + + ZBarSymbolSet *symbols = image.symbols; + for(ZBarSymbol *symbol in symbols) { + // process result + } + + This class is a simple wrapper around a :type:`zbar_symbol_set_t` C object + (q.v.) + + +Properties +---------- + + .. member:: int count + + The number of symbols in the set. (read-only) + + .. member:: const zbar_symbol_set_t *zbarSymbolSet + + Retrieve the underlying C object instance. (read-only) + + +Instance Methods +---------------- + + .. _`initWithSymbolSet:`: + .. describe:: - (id) initWithSymbolSet:(const zbar_symbol_set_t*)set + + Initialize a symbol set wrapper, given the C object to wrap. + + :set: The C object to wrap. + :Returns: The initialized symbol set, or nil if an error occurred. diff --git a/iphone/doc/apiref.rst b/iphone/doc/apiref.rst new file mode 100644 index 0000000..92920c0 --- /dev/null +++ b/iphone/doc/apiref.rst @@ -0,0 +1,16 @@ +******************* + API Reference +******************* + +.. toctree:: + :maxdepth: 1 + + ZBarImage + ZBarImageScanner + ZBarReaderController + ZBarReaderDelegate + ZBarReaderView + ZBarReaderViewController + ZBarReaderViewDelegate + ZBarSymbol + ZBarSymbolSet diff --git a/iphone/doc/camera.rst b/iphone/doc/camera.rst new file mode 100644 index 0000000..9f283dd --- /dev/null +++ b/iphone/doc/camera.rst @@ -0,0 +1,130 @@ +Scanning From the Camera Feed +============================= + +Many iOS developers want their application to support automatic recognition of +barcodes from the camera feed in real-time. ZBar makes this easy! + +There are three levels that you may choose to integrate at, from least complex +(recommended) to most complex these are: + +* Use the fully integrated view controller - this is very easy to implement + and is the recommended approach. +* Use the reader view with your own controller - this more advanced approach + allows you to embed the view directly in your view hierarchy. +* Use the capture component with your own AVCapture session - this is not + supported and only provided for advanced developers with special needs who + are already familiar with AVCapture. + + +Using a ZBarReaderViewController +-------------------------------- + +This is the fastest, easiest and recommend way to get the barcode reader into +your application. The procedure is the same as using a +UIImagePickerController to take a picture with the camera, so it will help if +you are familiar with that. Basically you: + +1. Create the reader. + + This is as simple as creating a new :class:`ZBarReaderViewController`:: + + ZBarReaderViewController *reader = [[ZBarReaderViewController alloc] init]; + +2. Setup a delegate to receive the results. + + The delegate should implement the :class:`ZBarReaderDelegate` protocol, + which inherits from :class:`UIImagePickerControllerDelegate`:: + + reader.readerDelegate = self; + +3. Configure the reader. + + Aside from the properties of the reader itself, you can configure the + decoder via the :member:`~ZBarReaderViewController::scanner` property and + further customize the view via the + :member:`~ZBarReaderViewController::readerView` property:: + + // disable QR Code + [reader.scanner setSymbology: ZBAR_QRCODE + config: ZBAR_CFG_ENABLE + to: 0]; + reader.readerView.zoom = 1.0; + + See :doc:`custom` and :doc:`optimizing` for more details. + +4. Present the reader to the user. + + Typically the controller is presented modally:: + + [self presentModalViewController: reader + animated: YES]; + + Alternatively, it may be added to a container controller. + +5. Process the results. + + The controller will call the + ``imagePickerController:didFinishPickingMediaWithInfo:`` method of + your delegate every time new results become available. The barcode data + can be obtained using the :c:data:`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 :c:data:`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 type of the reader (not + necessarily a :class:`UIImagePickerController`). + + .. note:: + + The delegate method should queue the interface response 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 (or not). + + Once you have the results you may 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. + + Alternatively, you may choose to continue scanning and provide visual + feedback another way (eg, maybe by updating your custom overlay with the + results). The "continuous" mode of the readertest example does this. + + +Using a ZBarReaderView +---------------------- + +:class:`ZBarReaderViewController` is a relatively thin wrapper around a +:class:`ZBarReaderView`; it is possible to use the view directly, even from +Interface Builder. You lose only some of the simulator and rotation hooks. +The documentation is also less complete, so you need to be able to UTSL. See +the :file:`EmbedReader` sample for a working example. + + +Using the ZBarCaptureReader +--------------------------- + +If you have special requirements for the capture session or just want to use +your own preview, you can add your own :class:`ZBarCaptureReader` to your +session. You must have a solid understanding of the AVCapture infrastructure +if you plan to use this approach. + +.. admonition:: TBD + + sorry, you're on your own here - UTSL :) diff --git a/iphone/doc/compat.rst b/iphone/doc/compat.rst new file mode 100644 index 0000000..5fb808e --- /dev/null +++ b/iphone/doc/compat.rst @@ -0,0 +1,190 @@ +Backward Compatibility +====================== + +Generally speaking, we take great care to ensure that each release of the +library is backward compatible with previous versions - upgrading the library +should not require any changes to your code and will continue to provide +equivalent functionality. The notable exception to this is the iOS 4 upgrade +and associated "deprecation" of the former automatic capture method by our +vendor. + + +.. warning:: + + Versions before iOS 4 are no longer supported by the library. We are no + longer able to test anything in this section, so you're on your own if you + try to make use of it. + + +The Private API +--------------- + +The API that we use for automatic capture with iOS 3.x (namely +:func:`UIGetScreenImage`) has an interesting history. It has changed status +several times, starting with "Private, unless we like you" moving to +"reluctantly Public but undocumeted" by popular demand and reverting to +"strictly Private" as of iOS 4. The current story: if you want to distribute +on the App Store, you had better not be using it - IOW, no automatic capture +for you with iOS 3.x. + +Since App Store distribution is the most common use for the library, the +default configuration, and thus the binary SDK, does *not* use any private +APIs. + +Users targeting ad-hoc or enterprise distribution may not care about the +status of the API and may prefer to continue supporting automatic capture for +iOS 3.x. To do this you will need to rebuild the library with the following +define set for all configurations: + +.. sourcecode:: sh + + USE_PRIVATE_APIS=1 + +For reference, you can check whether your app refers to the offensive function +with this command: + +.. sourcecode:: sh + + $ otool -vI MyApp.app/MyApp | grep UIGetScreenImage + +If there is any output, then the executable includes the private API and is +bound to be rejected if submitted for review. Otherwise it is "clean" as far +as this library is concerned. + + +Upgrading to iOS 4 +------------------ + +If you were using the reader before iOS 4 was introduced, you will want to +upgrade to the new reader controller. The performance has improved quite a +bit, and you can continue to support automatic capture on the App Store. + +.. note:: + + This discussion only applies to automatic capture from the camera. If you + are only scanning image files, or prefer/need to use manual capture, you + should not change anything. + +Basically just replace your old :class:`ZBarReaderController` with a new +:class:`ZBarReaderViewController` and you're done! See the reference and the +next section for compatibility between the two classes. + +Also see the :doc:`install` instructions for details about upgrading the +header references to use the SDK. + + +Supporting iOS 3.x +------------------ + +The new :class:`ZBarReaderViewController` is intentionally designed to be +compatible with the old :class:`ZBarReaderController` in most aspects that +relate to reading barcodes. When a :class:`ZBarReaderViewController` is +initialized under iOS 3.x, it will *replace* itself with a +:class:`ZBarReaderController`. You can leverage the compatibility of these +controllers to continue supporting iOS 3.x. + +The following properties and methods should be equivalent across +implementations. You may use them without regard for the actual instance +type. + +======================================================== ==== +Equivalent Members +======================================================== ==== +:member:`~ZBarReaderViewController::cameraOverlayView` +:member:`~ZBarReaderViewController::cameraViewTransform` +:member:`~ZBarReaderViewController::enableCache` +:member:`~ZBarReaderViewController::scanner` +:member:`~ZBarReaderViewController::readerDelegate` +:member:`~ZBarReaderViewController::scanCrop` +``showHelpWithReason:`` +:member:`~ZBarReaderViewController::showsZBarControls` +:member:`~ZBarReaderViewController::tracksSymbols` +======================================================== ==== + +Some properties are available with :class:`ZBarReaderViewController` only for +backward compatibility. If these are configured, they must be set as +indicated; attempts to set another value will raise an exception. + +==================================================== ======================================= +:class:`ZBarReaderController` Property :class:`ZBarReaderViewController` Value +==================================================== ======================================= +:member:`~ZBarReaderController::allowsEditing` ``NO`` +:member:`~ZBarReaderController::cameraMode` ``Sampling`` +:member:`~ZBarReaderController::maxScanDimension` (ignored) +:member:`~ZBarReaderController::showsCameraControls` ``NO`` +:member:`~ZBarReaderController::showsHelpOnFail` (ignored) +:member:`~ZBarReaderController::sourceType` ``Camera`` +:member:`~ZBarReaderController::takesPicture` ``NO`` +==================================================== ======================================= + +Also, the ``isSourceTypeAvailable:`` class method of +:class:`ZBarReaderViewController` will return ``YES`` only for the ``Camera`` +source. + +All other members of :class:`ZBarReaderController`, including those inherited +from :class:`UIImagePickerController` are not supported by +:class:`ZBarReaderViewController`. This includes ``takePicture`` and +``scanImage:``, among others. + +Remaining members of :class:`ZBarReaderViewController`: are only available +with the new implementation. At the moment this is only +:member:`~ZBarReaderViewController::readerView`, but any new properties or +methods not listed here will also fall in this category. + +To access settings that may not be available in a potential fallback +environment, you must verify that they exist and may be set as desired - eg, +by testing the specific reader subtype. + +Weak Linking +^^^^^^^^^^^^ + +When leveraging fallbacks to iOS 3.x, it is important that features introduced +in iOS 4 are referenced using *weak* links. You must configure your project +correctly to support this: + +* Make sure the iOS 4 frameworks are set to *Weak*. Specifically, these are + AVCapture, CoreMedia and CoreVideo. + +* Build with the latest SDK - do *not* use the "Base SDK" setting to target + earlier devices. + +* Set the correct iOS 3.x version for the "iPhone OS Deployment Target" + build setting. + + +Example: Fallback to Manual Capture +----------------------------------- + +This code example will configure the reader for automatic capture from the +camera for iOS 4 and fall back to manual or automatic capture for iOS 3.x, +depending on whether the library was compiled to use private APIs:: + + if(![ZBarReaderController isSourceTypeAvailable: + UIImagePickerControllerSourceTypeCamera]) { + // camera unavailable: display warning and abort + // or resort to keypad entry, etc... + return; + } + + ZBarReaderViewController *reader = [ZBarReaderViewController new]; + // reader will be a ZBarReaderController for iOS 3.x + // or a ZBarReaderViewController for iOS 4 + + reader.readerDelegate = self; + reader.sourceType = UIImagePickerControllerSourceTypeCamera; + reader.showsZBarControls = YES; + + if(reader.cameraMode == ZBarReaderControllerCameraModeSampling) { + // additional automatic capture configuration here + } + else { + // additional manual capture configuration here + } + + [self presentModalViewController: reader + animated: YES]; + +If you are using a custom control set +(:member:`~ZBarReaderViewController::showsZBarControls`\ ``=NO``), you will +want to provide a button attached to ``takePicture`` for the manual capture +case. The built-in controls do this automatically. diff --git a/iphone/doc/conf.py b/iphone/doc/conf.py new file mode 100644 index 0000000..950defb --- /dev/null +++ b/iphone/doc/conf.py @@ -0,0 +1,77 @@ +import sys, os +from plistlib import readPlist + +# General configuration + +extensions = [] +templates_path = ['ext'] +source_suffix = '.rst' +master_doc = 'index' +exclude_patterns = ['.#*'] + +project = u'ZBar iPhone SDK' +copyright = u'2010-2012, Jeff Brown et al' + +today_fmt = '%Y-%m-%d' +info = readPlist('../res/ZBarSDK-Info.plist') +version = 'X.Y' +if info: + version = info['CFBundleVersion'] +release = version + +#add_module_names = False + +pygments_style = 'sphinx' +highlight_language = 'objc' +primary_domain = 'cpp' + +# Options for HTML output + +html_theme = 'default' +html_theme_options = { + 'bgcolor': 'white', + 'textcolor': 'black', + 'linkcolor': '#247', + 'headbgcolor': '#edeff0', + 'headtextcolor': '#247', + 'headlinkcolor': '#c11', + 'sidebarbgcolor': '#247', + 'sidebartextcolor': 'white', + 'sidebarlinkcolor': '#cde', + 'relbarbgcolor': '#247', + 'relbartextcolor': '#ccc', + 'relbarlinkcolor': 'white', + 'footerbgcolor': 'white', + 'footertextcolor': 'black', + 'codebgcolor': '#dfe', + 'codetextcolor': 'black', +} + +html_short_title = 'ZBarSDK ' + version +html_title = 'ZBar iPhone SDK Documentation' +html_static_path = ['static'] +html_favicon = '../../zbar.ico' +html_style = 'style.css' +html_use_modindex = False +html_use_index = False +html_copy_source = False +html_show_sourcelink = False +htmlhelp_basename = 'doc' + +# Options for LaTeX output + +latex_paper_size = 'letter' +latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]) +latex_documents = [ + ('index', 'ZBarSDK.tex', u'ZBar iPhone SDK Documentation', + u'Jeff Brown', 'manual'), +] + +#latex_logo = '' +#latex_use_parts = False +#latex_preamble = '' +#latex_appendices = [] +#latex_use_modindex = False diff --git a/iphone/doc/custom.rst b/iphone/doc/custom.rst new file mode 100644 index 0000000..17f337f --- /dev/null +++ b/iphone/doc/custom.rst @@ -0,0 +1,70 @@ +Customizing the Interface +========================= + +The reader supports customization of the camera overlay and the integrated +help that is displayed. + + +Customizing the Overlay +----------------------- + +If you are scanning with the camera, whether using a +:class:`ZBarReaderViewController` for automatic capture or manually with +:class:`ZBarReaderController`, you may want to customize the appearance of the +reader. You do this mainly by setting a +:member:`~ZBarReaderViewController::cameraOverlayView`. + +Note that if you are scanning images from the photo library, there is no +customization - you are limited to the system picker interface provided by the +:class:`UIImagePickerController`. + +If you are using a :class:`ZBarReaderViewController` and just want to add to +the existing controls, you can simply set your overlay to include the +additional view hierarchy:: + + reader.cameraOverlayView = myLogoImageView; + +Otherwise, if you are using a :class:`ZBarReaderController` or prefer to +completely replace the default controls, you should disable those first. Note +that you will need to provide your own controls, which should at least include +a way to dismiss the reader:: + + reader.showsCameraControls = NO; // for UIImagePickerController + reader.showsZBarControls = NO; + reader.cameraOverlayView = myControlView; + +For manual capture with :class:`ZBarReaderController`, you should also include +a control connected to :member:`~ZBarReaderController::takePicture`. + +In either case, the overlay view may be loaded from a NIB, or simply created +programmatically. + +You can also disable the tracking rectangle that highlights barcodes with +:member:`~ZBarReaderViewController::tracksSymbols`. + + +Presenting Help +--------------- + +If you have set ``showsZBarControls = NO`` and replaced the default controls, +you may still present the built-in help viewer. Just hook your custom control +to the ``showsHelpWithReason:`` method of the controller. You should only +call this method when the reader is actually presented. + +The default reader controls invoke ``showsHelpWithReason:`` with a reason +parameter of ``"INFO"`` when the info button is tapped. + + +Customizing the Help Content +---------------------------- + +Whether you use the default controls or provide your own, you can still +customize the content of the help that is displayed. The integrated viewer +uses a UIWebView to display the contents of :file:`zbar-help.html` that we +copied into your Resources. You should hack this up as you see fit to give +your users the best help experience. + +To allow for runtime customization based on the reason for presenting help, +the javascript function ``onZBarHelp`` will be called just before the page is +displayed, with the ``reason`` argument set as provided to +``showsHelpWithReason:``. diff --git a/iphone/doc/devguide.rst b/iphone/doc/devguide.rst new file mode 100644 index 0000000..d794e2f --- /dev/null +++ b/iphone/doc/devguide.rst @@ -0,0 +1,13 @@ +*********************** + Developer's Guide +*********************** + +.. toctree:: + :maxdepth: 2 + + camera + picker + custom + optimizing + compat + licensing diff --git a/iphone/doc/faq.rst b/iphone/doc/faq.rst new file mode 100644 index 0000000..7689fd3 --- /dev/null +++ b/iphone/doc/faq.rst @@ -0,0 +1,101 @@ +Frequently Asked Questions (FAQ) +================================ + +This is the ever-growing list of answers to commonly asked questions. Please +feel free to post you question in our `iPhone Developers forum`_ if you do not +find the information you need in this documentation. + +.. _`iPhone Developers Forum`: + http://sourceforge.net/projects/zbar/forums/forum/1072195 + + +General +------- + +This looks great... Where can I get it? + You can download the latest version of the SDK from + http://zbar.sf.net/iphone + + +Compatibility +------------- + +Which iPhone devices does this library support? + The library works *only* with iOS devices that have an auto-focus camera. + Currently, the iPhone 3GS, iPhone 4 and newer devices. The iPad 2 and iPad + 3 will also work in many cases, *iff* the barcode is printed large enough + to achieve good focus. + +Will you make it work with the iPhone 3G? + *No* - the 3G it is not supported and is unlikely to ever be supported. + + To be fair, you *can* use the 3G to scan image files, as long as they're in + focus (ie, *not* images taken by the built-in fixed-focus camera). There + is at least one application that found a use for this... + +What target iOS versions does this library work with? + iOS 4, 5 and 6 are fully supported, including the latest video streaming + interfaces. Since Apple has dropped support for earlier versions of iOS on + the App Store, we recommend that you target only iOS 4 and later for reading + barcodes. + + Note that iOS 3.1 is no longer supported; if you really think you need + that, you should still be able to get it working... See :doc:`compat` for + details about iOS version fallbacks. + + In all cases you should use the latest SDK to build. + +Are any private APIs in use? + No - the binary release of the SDK does not use any private APIs. + +Does this support "automatic" barcode capture? + Yes - with recent iOS versions, the default configuration will capture + barcodes automatically from the video stream. + + +Building +-------- + +I get "Undefined symbols" errors when I try to build? + Most likely you did not add all of the necessary framework dependencies. + See :doc:`tutorial` or :doc:`install` for the list of frameworks you need + to link against. + + +Licensing +--------- + +Please refer to :doc:`licensing` for questions about licensing. + + +Barcodes +-------- + +Why do my UPC barcodes have an extra 0 at the front? + The UPC-A_ symbology is the subset of EAN-13_ that starts with a leading 0. + The ZBar decoder enables only EAN-13_ by default, so GTIN-13_ product codes + are consistently reported. You can choose to receive the 12-digit results + instead by explicitly enabling UPC-A_. + + The :member:`~ZBarSymbol::type` property of the symbol can be used to see + which type of barcode is reported. + + See EAN-13_ and UPC-A_ for more information. + +Why does my UPC-E (short version) barcode data look completely wrong? + UPC-E_ is a "zero compressed" version of UPC-A_; certain of the zeros are + removed from the UPC-A_ data to generate the UPC-E_ barcode. The ZBar + decoder *expands* this compression by default, again to consistently report + GTIN-13_ product codes. You can choose to receive the compressed 8-digit + results instead by explicitly enabling UPC-E_. + + The :member:`~ZBarSymbol::type` property of the symbol can be used to see + which type of barcode is reported. + + See UPC-E_ for more information. + +.. _GTIN-13: +.. _GTIN: http://wikipedia.org/wiki/GTIN +.. _EAN-13: http://wikipedia.org/wiki/EAN-13 +.. _UPC-A: http://wikipedia.org/wiki/UPC-A +.. _UPC-E: http://wikipedia.org/wiki/UPC-E#UPC-E diff --git a/iphone/doc/getstarted.rst b/iphone/doc/getstarted.rst new file mode 100644 index 0000000..29cf9e4 --- /dev/null +++ b/iphone/doc/getstarted.rst @@ -0,0 +1,12 @@ +********************* + Getting Started +********************* + +.. toctree:: + :maxdepth: 2 + :numbered: + + install + tutorial + faq + support diff --git a/iphone/doc/index.rst b/iphone/doc/index.rst new file mode 100644 index 0000000..6ded7c8 --- /dev/null +++ b/iphone/doc/index.rst @@ -0,0 +1,20 @@ +################ + ZBar iOS SDK +################ + +Welcome to the ZBar SDK for iOS! + +This documentation covers all aspects of developing with the SDK: from adding +the SDK to your project, to writing code that uses it, even licensing the +library with your app. + +Please let us know if you find anything inaccurate or lacking (even better, +send doc patches!) + +.. toctree:: + :maxdepth: 2 + :numbered: + + getstarted + devguide + apiref diff --git a/iphone/doc/install.rst b/iphone/doc/install.rst new file mode 100644 index 0000000..b86ac45 --- /dev/null +++ b/iphone/doc/install.rst @@ -0,0 +1,141 @@ +Installing the SDK +================== + +These are the basic instructions for obtaining the SDK and adding it to an +Xcode project. + +You may want to try things out with the :doc:`tutorial` before hacking at your +own project. + + +Requirements +------------ + +You will need *all* of the following to develop iPhone applications +using this SDK: + +* Mac OS X >= 10.6.x (Snow Leopard) +* Xcode >= 4.5.1 +* iPhone SDK >= 4.0 +* An iPhone 3GS, iPhone 4 or newer iOS device with an auto-focus camera +* iOS >= 4.0 running on the device + +.. warning:: + + *Only* the iPhone 3GS, iPhone 4 and newer models are supported, as they + have a camera with auto-focus. The iPad 2 and iPad 3 will also work, *iff* + the barcode is printed large enough to achieve good focus. The ZBar + library does not support the iPhone 3G and is unlikely to ever support it. + + +Downloading +----------- + +Download the latest binary release of the ZBar SDK from + +http://zbar.sourceforge.net/iphone + + +Integration +----------- + +The recommended installation method is to simply copy the SDK into your +Xcode project: + +1. Open ZBarSDK-|version|.dmg in the Finder. + +2. Drag the :file:`ZBarSDK` folder into your Xcode project. In the dialog + that appears, you should choose to **copy** the SDK into your project by + checking the box. The target that you want to link with the library should + also be selected in the target list. + +3. Link the following additional frameworks to any targets that link with the + ZBarSDK. You should set the first three to use weak references and + configure an appropriate deployment target if you still need to support + iOS 3: + + * :file:`AVFoundation.framework` (weak) + * :file:`CoreMedia.framework` (weak) + * :file:`CoreVideo.framework` (weak) + * :file:`QuartzCore.framework` + * :file:`libiconv.dylib` + + If you check "Link Binary With Libraries" for the target(s), you should see + all of these frameworks followed by :file:`libzbar.a`. + + .. note:: + + Link order may be important for some versions of Xcode; the referenced + libraries should be listed *before* :file:`libzbar.a` in the link order. + +4. Import the SDK header from your prefix header to make the barcode reader + APIs available:: + + #import "ZBarSDK.h" + +Proceed to :doc:`camera` or :doc:`picker` to learn about using the reader APIs +to scan barcodes. Use the :doc:`apiref` for specific interface details. + + +Upgrading from an Older Version +------------------------------- + +If you are using an older version of the *SDK* (NB, skip to the next section +if you are currently using Mercurial), upgrading is straightforward: + +1. Delete the current ZBarSDK group from your project. You should choose + to delete the files if you copied them into your project. +2. Drag the new ZBarSDK from the DMG into your project. + +Clean out and rebuild your project with the new version. + + +Upgrading a Pre-SDK Integration +------------------------------- + +If your project was using the library directly from the Mercurial repository, +before the SDK was introduced, there are a few incompatibilities that you must +resolve in order to upgrade. Don't worry - all of your source stays the same, +you just need to update how the library is included in the project and how the +headers are imported. + +Switching to the Binary Distribution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This approach is recommended - the binary releases provide you with a stable +development platform, isolating you from temporary instability and transient +problems that may occur at the bleeding edge. + +The first task is to reverse the previous ZBar integration: + +1. Remove the reference to zbar.xcodeproj from your project. +2. Remove any :file:`zbar-*` files from your Resources. +3. In the target build settings, remove any "Header Search Paths" that + reference zbar. +4. Remove any references to zbar headers in your :file:`prefix.pch` or source + files. + +Now just continue with the `integration`_ instructions above and you should be +back up and running! + +Continuing with Mercurial +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Alternatively, you may still prefer to select Mercurial revisions. You have a +few choices for this: + +* You may build your own ZBarSDK and copy/link it into your project. This is + the same as `Switching to the Binary Distribution`_, except that you use + your own version of the SDK. In this case you need to manually rebuild the + SDK when you update it. +* You may leave zbar.xcodeproj as a project dependency and pull the SDK into + your project. This is not well tested, so ymmv. +* You may leave zbar.xcodeproj as a project dependency and just link libzbar.a + into your project, as before. You will need to update the target dependency + (the library target changed names to libzbar) and add the + :file:`iphone/include/ZBarSDK` directory to "Header Search Paths" + +In any case, you should remove the references to the zbar headers from +:file:`prefix.pch` (or your source files) and replace them with:: + + #import "ZBarSDK.h" diff --git a/iphone/doc/licensing.rst b/iphone/doc/licensing.rst new file mode 100644 index 0000000..075ccd4 --- /dev/null +++ b/iphone/doc/licensing.rst @@ -0,0 +1,187 @@ +Licensing the Library +===================== + +First of all, the big disclaimer: + +.. warning:: + + We are *not* lawyers; we cannot help you decide if you should use the + library or how to apply the license, only your lawyer can advise you + concerning legal matters. + +That said, it should also be noted that we have neither the resources (time, +cash, etc) nor the patience to enforce the license (at all); the reality is +that all of this is left to your discretion. + +If you prefer to leave the lawyers out of it, the rest of this section will +help you apply the license to your application. + + +Licensing FAQ +------------- + +Can I use this library with my proprietary (closed source) application? + Yes, that is our intent and we do not believe there is any problem + regarding the license. + +Will I need to open source my entire app? + No, it is not required by the license. + +Will I need to distribute all of my "object files" on the App Store? + No, this is also not required by the license, although you should offer to + provide them upon request. See below for more detail. + +But I read somewhere that "iPhone apps may not use LGPL code"? + That statement is an over-generalization that does not apply in this case. + Most likely your source is either: + + * referring to the GPL, which is significantly different from the + *L*\ GPL + * referring to a different version of the LGPL; we intentionally use + version 2.1, which has specific static linking exceptions. + * not a lawyer either and too lazy to read the whole license + + Basically, if you leverage the appropriate sections of the license, it + should be fully compatible with the App Store restrictions and + requirements. + +This is too complicated, can I just pay for an easier license? + No, it is not possible. There are multiple problems with this approach, + some brief highlights: + + * Most open source projects (including this one) do not have a single + author. Tracking down every contributor and getting their approval could + be quite a challenge. + * The license is meant to protect users' rights to the software. Giving + you special treatment bypasses the protection we offered them, + effectively revoking their rights. This would be a violation of their + trust and completely defeats the purpose of the license. + + You may think of this as the "price" you pay for using our open source + library. If you want to make your life easier, you should be petitioning + Apple for shared library support... + +What if you add a clause that lets me do whatever I want? + No, also not possible. In addition to the problems mentioned above, there + are even more problems with this: + + * Sourceforge requires an OSI approved license for hosting our project; + an altered license would no longer be approved. + * Again we are not lawyers and therefore not qualified to change the + license, we would have to pay one of those slimy buggers to do it. + +Do I need to add an "about" dialog to display your copyright/license? + No, not as such. We won't discourage you from plugging the library if you + like, but it is not a requirement. You should think of our license as a + supplement to your own software license, therefore it is appropriate to + display it where (and only where) you display your own: + + * If you follow Apple's recommendation, the App Store is the only place + that the user accesses your license, so it should also be the only place + where the library supplement is available. + * If your app already has some kind of "about" view that displays your + copyright/license information, it is also appropriate to display the same + information for the library. + +Do I need to include the entire library in my application bundle? + No, it is not necessary: + + * If you have not modified the library, it is sufficient to provide a link + to the project and the version information. + * If you are using a modified version, you may provide a link to download + that instead of including it in the bundle. + + +Modifications +------------- + +What is a "modification"? Again, we leave it to your discretion with this +guidance: + +* If you use the distributed binary SDK you have certainly not modified the + library. +* If you are working from Mercurial, *any* change you have made to the + "source code" of the library is a modification, it does not matter how + trivial. You can see what changes have been made by running + ``hg status -mard``; if this command outputs anything, you have modified + the library. + +If you find that you have made changes to the library, you should carefully +consider how far you want to proceed down that path. Once you publish your +changes you have created a "fork" of the project which you now need to +maintain. Are you prepared to merge every time the library is updated? + +If your change adds a useful feature to the library, we absolutely encourage +you to submit patches. Assuming you can get your patch into the project, then +you will no longer need to use a modified version! When submitting patches, +ensure that your changes are appropriate for all of our users. Specifically, +we are not interested in patches that simply hack up the library to work the +way you want. Compare a patch that changes the default behavior to your +preference (probably not acceptable), to a patch that adds a new configuration +to support the feature you have added (probably fine). + + +Object File Distribution +------------------------ + +Section 6 of the LGPL v2.1 specifically permits static linking with the +library. If your project is not open source, this section does require that +you make your object files available to your users. The intent, as indicated +in the license, is that a user who has obtained your software may exercise +their right to modify the library and then re-link their modified version into +your application. + +We recommend that you apply Subsection 6c, which only requires that you make a +written offer to provide the object files. Now...if you consider the actual +utility of this mechanism - that it is only applicable to developers, and only +those with in depth knowledge of the tools, the time required for development +- all to have a new barcode reader in a specific version of your application +that only they can use, the reality is that no one is going to request this. +You probably should not even waste time preparing for it until a request is +made. + +Additionally, to avoid "casual requests" from nefarious types that just want +to inconvenience you, also consider charging a fee for the distribution of +this material (as permitted by the license); just add up the cost of burning +and shipping a disk. If this cost is "large" compared to the price of your +app, the likelihood of a request is reduced even further. + + +Using the Unmodified Library +---------------------------- + +Applying the license in this case is somewhat simpler. These are the basic +steps you can follow: + +1. Verify that the rest of your software license is compatible with the LGPL. + You cannot use the library if they are incompatible. + + For those using the default App Store license, we have reviewed this and + believe it is compatible with the LGPL. + +2. At the end of your license text, in an annex or supplement, start by + declaring your use of the library and offering a link to the project. + Something like this: + + This software uses the open source ZBar Barcode Reader library, version + |version|, which is available from http://zbar.sourceforge.net/iphone + + If you built your own version of the library, replace the version callout + with eg, "cloned from Mercurial revision xxxxxxxx" + +3. Then append the contents of the text file COPYING, included with the + library. This is all of the copyright information for the library. + +4. Then append the contents of the text file LICENSE.md, also included with the + library. This is just the LGPL version 2.1 which you may also obtain from + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + +5. You may choose to make the written offer for the object files explicit. + Provide some text and whatever link or email address is appropriate. + + +Using a Modified Library +------------------------ + +We intentionally leave this option vague and force you to refer to the license +as an underhanded way of encouraging you to contribute back to the project ;) diff --git a/iphone/doc/optimizing.rst b/iphone/doc/optimizing.rst new file mode 100644 index 0000000..a823fd6 --- /dev/null +++ b/iphone/doc/optimizing.rst @@ -0,0 +1,435 @@ +Optimizing the Reader +===================== + +As good as the iPhone performance is for a mobile device, the reality from an +image processing perspective is that it represents a lower performance target. +While the default configuration of the iPhone reader has been carefully tuned +for the general case, you can often obtain much better results if you optimize +for your specific application. + +.. note:: + + Performance is a complex topic. The only way to tune performance is by + changing settings and comparing measured results. If you are not + comfortable with the concepts presented here, it is recommended that you + leave the settings at the defaults and avoid compromising reliability. + +Performance of the barcode reader is generally evaluated by two factors: + +* The **latency** - how quickly it "recognizes" a barcode. Specifically this + is the time from when the user puts a barcode in the frame or selects an + image until a response is indicated back to the them. + +* The **reliability** - it does not matter how quickly an image is scanned if + an incorrect result is returned. That may seem obvious, but bad decodes + *are* possible and you need to keep this in mind when changing settings that + affect the reliability of the reader. + +Basically our goal is to optimize the latency without sacrificing reliability. +There are several factors that contribue to latency: + +* The **quality** of the barcode image. Quality includes the available + resolution, focus, lighting, noise, etc. We have more control over some of + these than others. + +* The **camera**. When scanning from the camera, the time for the + autoexposure and autofocus to converge on an image that can be decoded is a + significant contribution to the overall latency. + +* The **frame rate** of the reader - this translates to the time it takes the + scanner to process an image. + +* The **effort level** of the reader - some of the available settings control + "how hard" the reader tries to find barcodes in each frame. + +* The **delegate latency** - the time spent in your application after a + barcode has been detected until the user is notified. + +Most of these factors are interrelated. We will discuss those we can control +in detail, as well the settings you use to affect them. Then we will provide +a few specific case examples. + + +Measuring Performance +--------------------- + +Subjective response times are a good place to start (does it "feel" responsive +to you?), and possibly the only way to evaluate the overall experience, but to +compare incremental changes to interrelated settings and have meaningful +performance discussions with others, we need a more quantitative approach. + +The :func:`mach_absolute_time` function is a good tool for accurately +measuring small delays. Research this function and learn how to apply it. As +when measuring any real-world value, keep in mind that some variance is to be +expected - even if you perform exactly the same operation multiple times, you +will not see exactly the same measurement. You should collect several +samples, discard any obvious outliers, and average the remaining measurements. + +One way that the overall reader latency may be evaluated is by manually +marking the time when the barcode is presented to the reader. Add a control +to your overlay that captures the start time when tapped and compare this to +the end time, just before your delegate returns. + +The reader continually monitors the frame rate at which it is running. The +measured value may be displayed for debugging purposes by enabling the +:member:`~ZBarReaderView::showsFPS` property. The readertest example does +this and also provides control over many of the available settings, so you can +quickly test how each setting affects the frame rate. You should target your +optimization efforts to achieve a frame rate of at least 8-10fps, although +12-15fps is preferable. + +You can measure the latency of your delegate using :func:`mach_absolute_time`. +The measured value should be less than about 100ms, the smaller the better, to +avoid noticeable lag. + +The readertest is a good tool for testing the performance of the reader. You +can tune the settings appropriately for your application and evaluate the +effect each change has on the performance. + + +Delegate Latency +---------------- + +This latency contributor is the easiest for you to effect (and sometimes the +easiest to overlook). Your delegate method should update the interface - +dismiss the controller or update your overlay to indicate success - and +*nothing* else. All other processing should be deferred until after the +animations have started. + + +Image Quality +------------- + +Resolution +^^^^^^^^^^ + +One might think that "more is better" in terms of resolution, but this is not +necessarily the case. Given average image quality, the ideal resolution for +scanning is right around three pixels per barcode "module" (the width of the +smallest bar or space). Note that this measure is not an absolute image size +or even a measure of the physical dimensions represented by a pixel sample, it +*only* describes the sampled size of the barcode in the image. + +As the resolution decreases below about two pixels per module, edge fidelity +is lost and the bars and spaces start to merge together, making it impossible +(for this library) to scan. This affects the density (feature size) and +maximum size (data capacity) of the barcodes that can be detected. +Conversely, as the resolution increases above about 4 pixels per module, noise +can interfere with the edge detection and images will take longer to process. + +Other quality factors, such as poor focus, bad lighting or even excessive +noise, can increase (or decrease) the resolution requirement. + +When scanning from the camera, the reader defaults to 640x480, which is good +for most applications. On newer devices, you can increase this using a capture +:member:`~ZBarReaderView::session` preset. Some older devices do not have a +higher resolution option available. + +For scanning images, you can use +:member:`~ZBarReaderController::maxScanDimension` to control the scaled size +of the converted image, or resort to converting them yourself. + +If you want to read long linear barcodes or dense 2-D symbols, you will +probably want to increase the resolution by adjusting these settings. + +Keep in mind that more pixels will take longer to scan, refer to the `frame +rate`_ discussion for ways to compensate. + +Focus +^^^^^ + +Ideally we would fix the focus at a calculated optimum distance and optimize +the aperture selection to maximize the depth of field. Unfortunately the APIs +do not currently give us control over any of these settings, the best we can +do (as of iOS 4) is continuous auto-focus mode - this mode is configured by +the reader automatically. It can still take the device as long as 1-2 seconds +to find the appropriate macro focus setting, but again, there is currently no +way to reduce this delay. + +Lighting and Exposure +^^^^^^^^^^^^^^^^^^^^^ + +An image that is too bright or overexposed can completely wash out any +barcodes. An image that is too dark or underexposed will not provide +sufficient contrast for the scanner. Low light levels also tend to produce +noisier images, possibly because the driver uses a faster "ISO" setting to +compensate for the lighting. + +The camera defaults to continuous automatic exposure and white balance. Since +there are no other useful values, the reader leaves these unchanged from their +default setting. + +For some devices, the "torch" can be enabled to provide additional +illumination for the camera in low-light conditions. The reader sets the +torch to automatic by default, so it should turn on only when needed... +There have been some reports that the torch turns on inappropriately, washing +out the image. If you find that this occurs, you should instead set the +:member:`~ZBarReaderView::torchMode` property of the :class:`ZBarReaderView` +to ``Off``. + +For scanning images from another source, you are again stuck with the +available image quality. If you have any control over the image source, you +should do what you can to fix quality problems there. + +Noise +^^^^^ + +Some level of noise is filtered by the reader, but excessive noise levels +create additional edges in the image which corrupt barcodes and increase +scanning time (decreasing the frame rate). + +As mentioned with `lighting and exposure`_, noise mostly becomes a problem +when the light-level is too low, but high-resolution images may also increase +exposure to sensor noise. + +We compensate for noise by *reducing* the `resolution`_ from the sensor +maximum. Scaling the image down has the effect of averaging several pixels +into one value, filtering out the high-frequency noise component. + + +Frame Rate +---------- + +The time it takes to scan and decode an image/frame is roughly proportional to +the number of pixels that are processed. The number and type of enabled +symbologies and image noise can also affect the processing time. + +We have several knobs available that affect the frame rate. Most of these are +geared toward reducing the number of image pixels that are scanned. + +Decrease the Resolution +^^^^^^^^^^^^^^^^^^^^^^^ + +Adjusting the resolution of the image is an easy way to quickly reduce the +number of pixels. Smaller images also mean there is less data to carry +around, which helps performance in other ways. For example, reducing each +image dimension by 30% (eg, from 640x480 to 448x336) will about double the +speed of the reader (to a point). [FIXME verify!] + +Adjusting the resolution is `described above <resolution>`_. As mentioned +there, reducing the resolution will negatively impact the minimum feature size +and maximum barcode size that can be scanned, but it will help filter noise. + +Crop the Scan Region +^^^^^^^^^^^^^^^^^^^^ + +It may not always be necessary for an application to scan all the way to the +edges of the image. By cropping the scan area, you can get most of the +benefits of reduced resolution without sacrificing the minimum feature size. +Cropping will also not affect image noise, but similar to decreasing the +resolution, it does affect the maximum size barcode that can be scanned. + +For all cases you set the crop rectangle +:class:`~ZBarReaderViewController::scanCrop` property. Note that the +rectangle provided to the controller is *normalized* across image size and +rotation. This means that the coordinates range from 0 to 1 and the axes will +be arranged such that the x-axis of the crop rectangle corresponds to the +major (longer) image axis. + +Your interface will typically need to indicate the cropped scan area to the +user with visual queues. Use the +:class:`~ZBarReaderViewController::cameraOverlayView` to provide this. + +By default, the :class:`ZBarReaderView` recognizes a pinch gesture to +digitally zoom the preview around the center of the image. This zoom does not +affect the resolution of the image, but it does crop the scan region to the +visible area. You can also disable the pinch gesture and set the +:class:`~ZBarReaderView::zoom` programmatically. + +Limit the Scan Density +^^^^^^^^^^^^^^^^^^^^^^ + +The scanner works by making scan passes across the pixel rows and colums of +the image. The density of the passes is configured at the scanner as a pixel +stride for each axis. ``ZBAR_CFG_Y_DENSITY`` (``ZBAR_CFG_X_DENSITY``) +controls the number of pixel rows (columns) that are skipped between +successive horizontal (vertical) scan passes. (Note that "density" is really +not a good name for the configuration settings... "stride" might be more +appropriate.) + +Decreasing the scan density (by increasing the stride setting) is a great way +to limit the processing (increasing the frame rate) without sacrificing scan +resolution - each scan pass is still made at full image resolution, there are +just fewer passes (less redundancy). + +Setting the stride value to 0 completely disables scanning in that direction. +This is very useful when reading linear codes with a visual alignment guide - +scanning parallel to the bars is a waste of cycles which may be better applied +to support higher resolution or increased density of scans across the symbol. +Note that some 2-D symbologies (QR Code) require scans in both directions. + +Setting the stride to a very large value will generate a single scan pass +through the center of the image. Note that some symbologies will not be +detected without multiple successful passes; it is usually better to combine +this setting with cropping to generate a number of closely clustered scan +passes in the target area. + +Note that the density also affects the aspect ratio and rotation that can be +tolerated. If you set it too large, some barcodes will become more difficult +to read. + +In general, 2 to 4 is a good target for the stride setting, unless you have +very high or low resolution images. + +Disable unused symbologies +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Limiting the symbologies to the set of interest should provide a small +performance boost. It also improves decode reliability - it is impossible to +receive an incorrect or unexpected decode result from a symbology that is +disabled. + +The reader does support full auto-discrimination among the supported +symbologies, but with all of them enabled you may need to compensate elsewhere +to get a good frame rate. + +For example, if you are only interested in QR codes, disable the others. The +robust way to do this is by disabling *all* symbologies and then reenabling +only those you want. This helps isolate you from encountering new symbologies +that may be added in future versions of the library until you are ready to +handle them:: + + [scanner setSymbology: 0 + config: ZBAR_CFG_ENABLE + to: 0]; + [scanner setSymbology: ZBAR_QRCODE + config: ZBAR_CFG_ENABLE + to: 1]; + +Even if you would like your application to support multiple symbologies, you +may consider if there is a way to limit the enabled subset based on the +scanning context, etc... + + +Examples +-------- + +These examples demonstrate several scenarios for scanning from the camera with +automatic capture. You can try them yourself using the readertest. For each +example, start with the default settings (by tapping the +``ZBarReaderViewController`` class), then enable continuous mode and the +custom overlay (by disabling +:member:`~ZBarReaderViewController::showsZBarControls`). You should also use +a release build and avoid running in the debugger. + +Frame rates are approximate, measured on an iPhone 3GS running iOS 4.0.1 in a +well lit room. Two measurements are taken for each sample: the rate with the +camera pointed at a blank white page such that it fills the frame, and the +rate while continuously decoding the provided example. For best results, it +is recommended that you print the examples rather than scanning them from the +screen. + +For reference, the base frame rates with default settings are 12fps for a +blank white page, 7.5fps for this `basic EAN symbol`_ and 2.2fps for this +`basic QR symbol`_. + +.. _`basic EAN symbol`: + http://zbar.sf.net/test/ean13/9876543210128.png +.. _`basic QR symbol`: + http://chart.apis.google.com/chart?cht=qr&chs=512x512&chl=http://zbar.sf.net/iphone + +Long Linear Symbols +^^^^^^^^^^^^^^^^^^^ + +For this example, we will use a relatively `long Code 128 barcode`_. + +.. _`long Code 128 barcode`: + http://zbar.sf.net/test/code128/ALPHA.png + +While it should be possible to read this symbol with the default settings, you +may notice that it is not very reliable. You will have to stretch the symbol +across the entire screen, and even then the default settings will only give +you about 1.6 pixels per module, well below the ideal target of 3. To improve +these results, we want to maximize scanning resolution for the long image +axis. + +1. Disable the default zoom/crop - zoom all the way out by hitting "Scan" and + pinching the preview; the frame rate immediately drops to 8fps / 4.8fps. + +We should compensate for this reduction in the frame rate: + +2. Crop the image to a long, skinny rectangle - set the + :member:`~ZBarReaderViewController::scanCrop` setting to + ``{{0, 0.3}, {1, 0.4}}``; The frame rate jumps up to 18fps / 8.7fps. + +3. Disable scans across the short image axis - set the ``CFG_X_DENSITY`` + setting to 0. The frame rate goes all the way to 30fps / 13fps. + +Since we have plenty of margin with the frame rate, we can minimize the total +decode latency by performing more scan passes through the symbol: + +4. Increase the scan density - set the ``CFG_Y_DENSITY`` setting to 1 (13.5fps + / 5fps) or 2 (24fps / 9fps). + +You should now be able to quickly and reliably decode long linear symbols. + +If have a newer device, you may also try increasing the resolution to support +even longer symbols. You may have to compensate elsewhere to bring the frame +rate back to a reasonable level. + +High Density QR Symbols +^^^^^^^^^^^^^^^^^^^^^^^ + +For this example we will use a `version 29 QR Code symbol`_. + +.. _`version 29 QR Code symbol`: + http://www.qrcomic.com/images/5.png + +In this case we still want to maximize the resolution, but we also need to +increase the scan density to reliably pick up the small finder patterns: + +1. Maximize scan density in both directions - set the ``CFG_X_DENSITY`` and + ``CFG_Y_DENSITY`` settings both to 1. You should be able to scan the symbol + now, although the frame rate drops to 4.5fps / 1fps + +2. Disable the default zoom/crop - zoom all the way out by hitting "Scan" and + pinching the preview; the frame rate drops further to 3fps / 0.7fps + +We can compensate somewhat for the reduced frame rate: + +3. Crop the image to a square - set ``scanCrop`` to ``{{0.125, 0}, {.75, 1}}``. + This boosts the frame rate slightly to 3.7fps / 0.75fps. + +4. Disable linear symbologies - set the symbologies such that only QR Code is + enabled (4fps / 1fps) + +Even though the frame rate is still pretty bad, the QR recognition latency +should be acceptable. + +If have an iPhone 4, you may also try increasing the resolution to support +even denser QR symbols. You may have to compensate elsewhere to bring the +frame rate back to a reasonable level. + +Small DataBar Symbols +^^^^^^^^^^^^^^^^^^^^^ + +For this example we will use a `DataBar symbol`_ printed with a small feature +size, typical of the stickers used to tag produce. Scale it when printing +such that the printed dimensions are about 1cm square. This symbol should +scan with the default settings, but we will attempt to optimize the scan +latency for this case. + +.. _`DataBar symbol`: + http://zbar.sf.net/test/databar/0109876543210128-so.png + +As well as high barcode resolution, we also want high density passes in both +directions to minimize sensitivity to rotation: + +1. Maximize scan density in both directions - set the ``CFG_X_DENSITY`` and + ``CFG_Y_DENSITY`` settings both to 1. The frame rate drops to 4.5fps / + 3fps. + +Compensate for the reduction in frame rate by zooming in on the small symbol, +which crops the scanned image. Zooming also helps the user see the small +barcode: + +2. Zoom all the way in - hit "Scan" and un-pinch the preview. The frame rate + recovers to 11fps / 6.2fps. + +3. Crop the image to a square - set ``scanCrop`` to ``{{0.125, 0}, {0.75, 1}}`` + (14fps / 7.5fps) + +4. Disable all symbologies except DataBar and DataBar Expanded (14.5fps / 9fps) + +The reader should now be very sensitive to DataBar, even when scanned at an +angle. diff --git a/iphone/doc/picker.rst b/iphone/doc/picker.rst new file mode 100644 index 0000000..fe1ba58 --- /dev/null +++ b/iphone/doc/picker.rst @@ -0,0 +1,104 @@ +Scanning a User-Selected Image +============================== + +Some applications may need the full resolution offered by camera snapshots, or +need to scan an image or document from the user's photo library. In these +cases you use a :class:`ZBarReaderController`. This reader is a *subclass* of +:class:`UIImagePickerController`, and you use it the same way. See the +documentation for :class:`UIImagePickerController` for more detais. + +1. Create the reader. + + This is as simple as creating a new :class:`ZBarReaderController`:: + + ZBarReaderController *reader = [[ZBarReaderController alloc] init]; + +2. Setup a delegate to receive the results. + + The delegate should implement the :class:`ZBarReaderDelegate` protocol, + which inherits from :class:`UIImagePickerControllerDelegate`:: + + reader.readerDelegate = self; + +3. Configure the reader. + + You will need to set the :member:`~ZBarReaderController::sourceType` + appropriately. Aside from the properties of the reader itself, you can + configure the decoder via the :member:`~ZBarReaderController::scanner` + property:: + + if([ZBarReaderController isSourceTypeAvailable: + UIImagePickerControllerSourceTypeCamera]) + reader.sourceType = UIImagePickerControllerSourceTypeCamera; + [reader.scanner setSymbology: ZBAR_I25 + config: ZBAR_CFG_ENABLE + to: 0]; + + See :doc:`custom` and :doc:`optimizing` 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 + :c:data:`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 + :c:data:`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 :class:`ZBarReaderController` + (again, a subclass :class:`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. + + +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 :member:`~ZBarReaderController::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. diff --git a/iphone/doc/static/style.css b/iphone/doc/static/style.css new file mode 100644 index 0000000..721b5fb --- /dev/null +++ b/iphone/doc/static/style.css @@ -0,0 +1,36 @@ +@import url("default.css"); + +h1, h2, h3, h4, h5, h6 { + clear: both; +} + +img.logo { + vertical-align: middle; +} + +img.floatright { + float: right; + clear: both; + margin-left: 2em; + margin-right: 2em; +} + +dl.docutils dt { + font-weight: bold; +} +dl.docutils dd { + margin-top: 1em; + margin-bottom: 1em; +} + +table.docutils { + margin-left: auto; + margin-right: auto; +} +table.docutils th, table.docutils td { + padding: .25em .5em; +} + +table.docutils.field-list { + margin-left: 0; +} diff --git a/iphone/doc/support.rst b/iphone/doc/support.rst new file mode 100644 index 0000000..7cf8b55 --- /dev/null +++ b/iphone/doc/support.rst @@ -0,0 +1,19 @@ +Obtaining Support +================= + +If this documentation does not address your question/problem and you need +support, please feel free to post in our `iPhone Developers Forum`_. + +.. _`iPhone Developers Forum`: + http://sourceforge.net/projects/zbar/forums/forum/1072195 + +When posting, please: + +* Check the :doc:`faq` and the rest of this documentation first. +* Start a new thread for a new question - do not "hijack" an unrelated thread. +* Post complete details of your problem - complete error messages as well as + relevant source code and images. +* Log-in to receive email, or check back within a day or so - you will almost + always get a response. + +For the latest support information, please see http://zbar.sf.net/iphone diff --git a/iphone/doc/tutorial.rst b/iphone/doc/tutorial.rst new file mode 100644 index 0000000..3e10ade --- /dev/null +++ b/iphone/doc/tutorial.rst @@ -0,0 +1,228 @@ +ZBar SDK Integration Tutorial +============================= + +.. image:: ReaderSample.png + :alt: Screenshot of the ReaderSample app + :width: 414 + :height: 770 + :scale: 40 + :class: floatright + +This tutorial will quickly get you up and running with the ZBar iPhone SDK. + +We will develop a very simple app that presents a button the user can tap to +invoke the barcode reader and then displays the results. Interface Builder +will be used to create the interface. + +The completed project is also available with the distributed SDK under +:file:`Examples/ReaderSample`. + + +Create the App +-------------- + +1. Open Xcode; you must have version 4.5.1 or later. + +2. Create a new project using the "View-based Application" template. Name the + project "ReaderSample". Save it wherever you like. + +3. Open :file:`ReaderSampleViewController.xib` + +4. Drag a Round Rect Button onto the view and title it "Scan". Customize the + placement and appearance as you like. + +5. Drag an Image View onto the view. Size it to fill about half of the + remaining space. Change the view mode to Aspect Fit. + +6. Drag a Text View onto the view and size it to fill the remaining space. + Change the default text to "No barcode scanned" or something. De-select + "Editable" + +7. Add connections to the interface elements in the code; open + :file:`ReaderSampleViewController.h` and change the interface to:: + + @interface ReaderSampleViewController : UIViewController + { + UIImageView *resultImage; + UITextView *resultText; + } + @property (nonatomic, retain) IBOutlet UIImageView *resultImage; + @property (nonatomic, retain) IBOutlet UITextView *resultText; + - (IBAction) scanButtonTapped; + @end + +8. Now we can finish the interface connections - open + :file:`ReaderSampleViewController.xib` and make these connections: + + * Connect ReaderSampleViewController ``resultImage`` outlet to the + ImageView. + * Connect ReaderSampleViewController ``resultText`` outlet to the TextView. + * Connect ReaderSampleViewController ``scanButtonTapped`` action to the + RoundedRectButton(Scan) event ``TouchUpInside``. + + Consult the Xcode documentation if you need help making these connections. + Make sure you save the XIB once they are finished. + +9. Finish the implementation in :file:`ReaderSampleViewController.m`:: + + @synthesize resultImage, resultText; + + - (IBAction) scanButtonTapped + { + NSLog(@"TBD: scan barcode here..."); + } + + - (void) dealloc + { + self.resultImage = nil; + self.resultText = nil; + [super dealloc]; + } + + - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation + { + return(YES); + } + + This stub for scanButtonTapped is temporary, we'll fix it in a minute... + +Although it doesn't do much yet, you should now have a working skeleton app +that you can build and run. + + +Integrate the Reader +-------------------- + +Now for the exciting part - let's add a barcode reader! + +1. If you have not done so already, download the latest SDK from + http://zbar.sourceforge.net/iphone + +2. Double-click the disk image, ZBarSDK-|version|.dmg in the Finder to open it. + +3. Drag the :file:`ZBarSDK` folder into your Xcode project. Make sure that + the "Copy Items into destination group's folder" checkbox is checked. + +4. Open the target build settings and find ``Link Binary With Libraries``. + Click the ``+`` and add each of these (NB hold down command for multiple + selection): + + * AVFoundation.framework + * CoreMedia.framework + * CoreVideo.framework + * QuartzCore.framework + * libiconv.dylib + + .. warning:: + + Link order may be important for some versions of Xcode; the libraries + referenced above should be listed *before* :file:`libzbar.a` in the + link order. + +5. Import the SDK header. You will usually want to prefix it, so add it to + :file:`ReaderSample-prefix.pch`:: + + // ADD: import barcode reader APIs + #import "ZBarSDK.h" + +6. Declare support for the delegate protocol in + :file:`ReaderSampleViewController.h`:: + + @interface ReaderSampleViewController : UIViewController + // ADD: delegate protocol + < ZBarReaderDelegate > + { + ... + +7. Re-implement scanButtonTapped to present a barcode reader when the user + taps the Scan button. In :file:`ReaderSampleViewController.m`:: + + - (IBAction) scanButtonTapped + { + // ADD: present a barcode reader that scans from the camera feed + ZBarReaderViewController *reader = [[ZBarReaderViewController alloc] init]; + reader.readerDelegate = self; + reader.supportedOrientationsMask = ZBarOrientationMaskAll; + + ZBarImageScanner *scanner = reader.scanner; + // TODO: (optional) additional reader configuration here + + // EXAMPLE: disable rarely used I2/5 to improve performance + [scanner setSymbology: ZBAR_I25 + config: ZBAR_CFG_ENABLE + to: 0]; + + // present and release the controller + [self presentModalViewController: reader + animated: YES]; + [reader release]; + } + +8. Finally, implement the delegate method to do something useful with the + results. Still in :file:`ReaderSampleViewController.m`:: + + - (void) imagePickerController: (UIImagePickerController*) reader + didFinishPickingMediaWithInfo: (NSDictionary*) info + { + // ADD: get the decode results + id<NSFastEnumeration> results = + [info objectForKey: ZBarReaderControllerResults]; + ZBarSymbol *symbol = nil; + for(symbol in results) + // EXAMPLE: just grab the first barcode + break; + + // EXAMPLE: do something useful with the barcode data + resultText.text = symbol.data; + + // EXAMPLE: do something useful with the barcode image + resultImage.image = + [info objectForKey: UIImagePickerControllerOriginalImage]; + + // ADD: dismiss the controller (NB dismiss from the *reader*!) + [reader dismissModalViewControllerAnimated: YES]; + } + +And that's it! + + +Testing +------- + +1. Save everything (don't forget to save MyAppViewController.xib). + +2. Build and Run the project. + +3. Tap the Scan button. + +4. Aim at barcode. + +5. Enjoy the sweet fruits of your minimal labor + + +Where to go from here +--------------------- + +You can learn more about using the reader APIs to scan barcodes from +:doc:`camera` or :doc:`picker`. Use the :doc:`apiref` to find details about a +particular interface. + + +Troubleshooting +--------------- + +We take great care to ensure this tutorial is working as described. However, +if you do have a problem + +1. Make sure you followed the instructions exactly - every detail is + important. +2. Start from scratch with a new project and follow the instructions + *exactly*. +3. Try the ReaderSample distributed with the SDK and compare your work with + that. +4. If you are unable to get things working, you may post your frustrations in + the project `iPhone Developers Forum`_. Please be very specific about your + problem, post the complete text of any errors, etc. + +.. _`iPhone Developers Forum`: + http://sourceforge.net/projects/zbar/forums/forum/1072195 |