diff --git a/iphone/ChangeLog b/iphone/ChangeLog index 96c4435b..0fe308c5 100644 --- a/iphone/ChangeLog +++ b/iphone/ChangeLog @@ -1,4 +1,10 @@ +version 1.1.3: + * fix UITabViewController rotation interaction + version 1.1.2: + * add maxZoom for increasing zoom range + - workaround camera preview initial location/size bug + * add emulation for UI videoQuality to adjust camera resolution * fix several simulator-related bugs - fix device property missing from simulated ZBarReaderView - fix AVCaptureDevice referenced from ZBarReaderViewController diff --git a/iphone/ZBarReaderView.m b/iphone/ZBarReaderView.m index 40a484a6..cbb22560 100644 --- a/iphone/ZBarReaderView.m +++ b/iphone/ZBarReaderView.m @@ -33,7 +33,7 @@ @interface ZBarReaderViewImpl : NSObject @implementation ZBarReaderView @synthesize readerDelegate, tracksSymbols, trackingColor, torchMode, showsFPS, - zoom, scanCrop, previewTransform, captureReader; + zoom, maxZoom, scanCrop, previewTransform, captureReader; @dynamic scanner, allowsPinchZoom, enableCache, device, session; + (id) alloc @@ -111,6 +111,7 @@ - (void) _initWithImageScanner: (ZBarImageScanner*) scanner scanCrop = effectiveCrop = CGRectMake(0, 0, 1, 1); imageScale = 1; previewTransform = CGAffineTransformIdentity; + maxZoom = 2; pinch = [[UIPinchGestureRecognizer alloc] initWithTarget: self @@ -232,19 +233,23 @@ static inline CGFloat rotationForInterfaceOrientation (int orient) - (void) layoutSubviews { + CGRect bounds = self.bounds; + if(!bounds.size.width || !bounds.size.height) + return; + + [CATransaction begin]; if(animationDuration) { - [CATransaction begin]; [CATransaction setAnimationDuration: animationDuration]; [CATransaction setAnimationTimingFunction: [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]]; } + else + [CATransaction setDisableActions: YES]; + [super layoutSubviews]; - CGRect bounds = self.bounds; fpsView.frame = CGRectMake(bounds.size.width - 80, bounds.size.height - 32, 80 + 12, 32 + 12); - if(!bounds.size.width || !bounds.size.height) - return; // orient view bounds to match camera image CGSize psize; @@ -320,6 +325,7 @@ - (void) layoutSubviews tracking.borderWidth = imageScale; #ifndef NDEBUG + preview.backgroundColor = [UIColor yellowColor].CGColor; overlay.borderWidth = 2 * imageScale; cropLayer.borderWidth = 2 * imageScale; cropLayer.frame = CGRectMake(effectiveCrop.origin.x * imageSize.width, @@ -339,24 +345,29 @@ - (void) layoutSubviews [self resetTracking]; [self updateCrop]; - if(animationDuration) { - [CATransaction commit]; - animationDuration = 0; - } + [CATransaction commit]; + animationDuration = 0; } - (void) setImageSize: (CGSize) size { + zlog(@"imageSize=%@", NSStringFromCGSize(size)); imageSize = size; + + // FIXME bug in AVCaptureVideoPreviewLayer fails to update preview location + preview.bounds = CGRectMake(0, 0, size.width, size.height); + [self setNeedsLayout]; } - (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) orient duration: (NSTimeInterval) duration { - zlog(@"orient=%d", orient); - interfaceOrientation = orient; - animationDuration = duration; + if(interfaceOrientation != orient) { + zlog(@"orient=%d #%g", orient, duration); + interfaceOrientation = orient; + animationDuration = duration; + } } - (void) setScanCrop: (CGRect) r @@ -406,8 +417,8 @@ - (void) setZoom: (CGFloat) z { if(z < 1.0) z = 1.0; - if(z > 2.0) - z = 2.0; + if(z > maxZoom) + z = maxZoom; if(z == zoom) return; zoom = z; @@ -419,10 +430,14 @@ - (void) setZoom: (CGFloat) z animated: (BOOL) animated { [CATransaction begin]; - [CATransaction setAnimationDuration: .1]; - [CATransaction setAnimationTimingFunction: - [CAMediaTimingFunction functionWithName: - kCAMediaTimingFunctionLinear]]; + if(animated) { + [CATransaction setAnimationDuration: .1]; + [CATransaction setAnimationTimingFunction: + [CAMediaTimingFunction functionWithName: + kCAMediaTimingFunctionLinear]]; + } + else + [CATransaction setDisableActions: YES]; // FIXME animate from current value self.zoom = z; [self layoutIfNeeded]; diff --git a/iphone/ZBarReaderViewController.m b/iphone/ZBarReaderViewController.m index 0aced30a..a3e9caa2 100644 --- a/iphone/ZBarReaderViewController.m +++ b/iphone/ZBarReaderViewController.m @@ -87,12 +87,32 @@ return(AVCaptureTorchModeOff); } +static inline NSString* +AVSessionPresetForUIVideoQuality (UIImagePickerControllerQualityType quality) +{ +#if !TARGET_IPHONE_SIMULATOR + switch(quality) + { + case UIImagePickerControllerQualityTypeHigh: + return(AVCaptureSessionPresetHigh); + case UIImagePickerControllerQualityType640x480: + return(AVCaptureSessionPreset640x480); + case UIImagePickerControllerQualityTypeMedium: + return(AVCaptureSessionPresetMedium); + case UIImagePickerControllerQualityTypeLow: + return(AVCaptureSessionPresetLow); + } +#endif + return(nil); +} + @implementation ZBarReaderViewController @synthesize scanner, readerDelegate, showsZBarControls, supportedOrientationsMask, tracksSymbols, enableCache, cameraOverlayView, - cameraViewTransform, cameraDevice, cameraFlashMode, readerView, scanCrop; + cameraViewTransform, cameraDevice, cameraFlashMode, videoQuality, + readerView, scanCrop; @dynamic sourceType, allowsEditing, allowsImageEditing, showsCameraControls, showsHelpOnFail, cameraMode, takesPicture, maxScanDimension; @@ -136,6 +156,7 @@ - (void) _init cameraViewTransform = CGAffineTransformIdentity; cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto; + videoQuality = UIImagePickerControllerQualityType640x480; AVCaptureDevice *device = nil; #if !TARGET_IPHONE_SIMULATOR device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; @@ -272,6 +293,23 @@ - (void) initControls [view addSubview: controls]; } +- (void) initVideoQuality +{ + if(!readerView) { + assert(0); + return; + } + + AVCaptureSession *session = readerView.session; + NSString *preset = AVSessionPresetForUIVideoQuality(videoQuality); + if(session && preset && [session canSetSessionPreset: preset]) { + zlog(@"set session preset=%@", preset); + session.sessionPreset = preset; + } + else + zlog(@"unable to set session preset=%@", preset); +} + - (void) loadView { self.view = [[UIView alloc] @@ -307,6 +345,7 @@ - (void) viewDidLoad if(device && device != readerView.device) readerView.device = device; readerView.torchMode = AVTorchModeForUIFlashMode(cameraFlashMode); + [self initVideoQuality]; readerView.readerDelegate = (id)self; readerView.scanCrop = scanCrop; @@ -340,10 +379,13 @@ - (void) viewDidUnload - (void) viewWillAppear: (BOOL) animated { - zlog(@"willAppear: anim=%d", animated); + zlog(@"willAppear: anim=%d orient=%d", + animated, self.interfaceOrientation); [self initControls]; [super viewWillAppear: animated]; + [readerView willRotateToInterfaceOrientation: self.interfaceOrientation + duration: 0]; [readerView start]; UIApplication *app = [UIApplication sharedApplication]; @@ -542,6 +584,13 @@ - (void) setCameraCaptureMode: (UIImagePickerControllerCameraCaptureMode) mode @" for %@ property", mode, @"cameraCaptureMode"); } +- (void) setVideoQuality: (UIImagePickerControllerQualityType) quality +{ + videoQuality = quality; + if(readerView) + [self initVideoQuality]; +} + // ZBarHelpDelegate diff --git a/iphone/ZBarReaderViewImpl_Capture.m b/iphone/ZBarReaderViewImpl_Capture.m index 71914fc8..482c4727 100644 --- a/iphone/ZBarReaderViewImpl_Capture.m +++ b/iphone/ZBarReaderViewImpl_Capture.m @@ -106,9 +106,13 @@ - (void) initSubviews [[AVCaptureVideoPreviewLayer layerWithSession: session] retain]; - videoPreview.videoGravity = AVLayerVideoGravityResizeAspectFill; preview = videoPreview; - preview.frame = self.bounds; + CGRect bounds = self.bounds; + bounds.origin = CGPointZero; + preview.bounds = bounds; + preview.position = CGPointMake(bounds.size.width / 2, + bounds.size.height / 2); + videoPreview.videoGravity = AVLayerVideoGravityResizeAspectFill; [self.layer addSublayer: preview]; [super initSubviews]; diff --git a/iphone/ZBarReaderViewImpl_Simulator.m b/iphone/ZBarReaderViewImpl_Simulator.m index 238efff4..2e9c1f8d 100644 --- a/iphone/ZBarReaderViewImpl_Simulator.m +++ b/iphone/ZBarReaderViewImpl_Simulator.m @@ -105,6 +105,11 @@ - (void) setDevice: (AVCaptureDevice*) device // simulated camera does nothing with this } +- (AVCaptureSession*) session +{ + return(nil); +} + - (void) updateCrop { previewImage.frame = preview.bounds; diff --git a/iphone/doc/ZBarReaderView.rst b/iphone/doc/ZBarReaderView.rst index de161730..d434215d 100644 --- a/iphone/doc/ZBarReaderView.rst +++ b/iphone/doc/ZBarReaderView.rst @@ -51,7 +51,12 @@ Properties 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,2]. (default 1.25) + 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 diff --git a/iphone/doc/ZBarReaderViewController.rst b/iphone/doc/ZBarReaderViewController.rst index bd9bb1f7..6eee7d32 100644 --- a/iphone/doc/ZBarReaderViewController.rst +++ b/iphone/doc/ZBarReaderViewController.rst @@ -55,13 +55,19 @@ Properties .. member:: UIImagePickerControllerCameraDevice cameraDevice - The camera device to use for scanning. + 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 diff --git a/iphone/examples/readertest/ZBarSDK b/iphone/examples/readertest/ZBarSDK index b8e76663..7a373eaf 120000 --- a/iphone/examples/readertest/ZBarSDK +++ b/iphone/examples/readertest/ZBarSDK @@ -1 +1 @@ -../../build/Release-iphoneos/ZBarSDK \ No newline at end of file +../../build/Debug-iphoneos/ZBarSDK \ No newline at end of file diff --git a/iphone/examples/readertest/readertest.m b/iphone/examples/readertest/readertest.m index cf184212..d0c87ff9 100644 --- a/iphone/examples/readertest/readertest.m +++ b/iphone/examples/readertest/readertest.m @@ -4,6 +4,7 @@ CAMODE_SECTION, DEVICE_SECTION, FLASH_SECTION, + QUALITY_SECTION, CONFIG_SECTION, CUSTOM_SECTION, SYMBOL_SECTION, @@ -17,6 +18,7 @@ @"CameraMode", @"CaptureDevice", @"CameraFlashMode", + @"VideoQuality", @"Reader Configuration", nil, @"Enabled Symbologies", @@ -358,6 +360,18 @@ - (void) initControlCells [sections replaceObjectAtIndex: FLASH_SECTION withObject: flashModes]; + static NSString *const qualityNames[] = { + @"High", @"Medium", @"Low", @"640x480", nil + }; + NSMutableArray *qualities = [NSMutableArray array]; + for(int i = 0; qualityNames[i]; i++) + [qualities addObject: + [self cellWithTitle: qualityNames[i] + tag: i + checked: (reader.videoQuality == i)]]; + [sections replaceObjectAtIndex: QUALITY_SECTION + withObject: qualities]; + static NSString* const configNames[] = { @"showsCameraControls", @"showsZBarControls", @"tracksSymbols", @"enableCache", @"showsHelpOnFail", @"takesPicture", @@ -775,6 +789,12 @@ - (void) tableView: (UITableView*) view inSection: FLASH_SECTION]; break; + case QUALITY_SECTION: + reader.videoQuality = cell.tag; + [self setCheckForTag: reader.videoQuality + inSection: QUALITY_SECTION]; + break; + case CONFIG_SECTION: { BOOL state; NSString *key = cell.textLabel.text; diff --git a/iphone/include/ZBarSDK/ZBarReaderView.h b/iphone/include/ZBarSDK/ZBarReaderView.h index 270be193..bc75c9d2 100644 --- a/iphone/include/ZBarSDK/ZBarReaderView.h +++ b/iphone/include/ZBarSDK/ZBarReaderView.h @@ -49,7 +49,7 @@ ZBarCaptureReader *captureReader; CGRect scanCrop, effectiveCrop; CGAffineTransform previewTransform; - CGFloat zoom, zoom0; + CGFloat zoom, zoom0, maxZoom; UIColor *trackingColor; BOOL tracksSymbols, showsFPS; NSInteger torchMode; @@ -106,12 +106,15 @@ @property (nonatomic) BOOL showsFPS; // zoom scale factor applied to video preview *and* scanCrop. -// also updated by pinch-zoom gesture. clipped to range [1,2], +// also updated by pinch-zoom gesture. clipped to range [1,maxZoom], // defaults to 1.25 @property (nonatomic) CGFloat zoom; - (void) setZoom: (CGFloat) zoom animated: (BOOL) animated; +// maximum settable zoom factor. +@property (nonatomic) CGFloat maxZoom; + // the region of the image that will be scanned. normalized coordinates. @property (nonatomic) CGRect scanCrop; diff --git a/iphone/include/ZBarSDK/ZBarReaderViewController.h b/iphone/include/ZBarSDK/ZBarReaderViewController.h index cbf4d09f..be2bf213 100644 --- a/iphone/include/ZBarSDK/ZBarReaderViewController.h +++ b/iphone/include/ZBarSDK/ZBarReaderViewController.h @@ -52,6 +52,7 @@ NSUInteger supportedOrientationsMask; UIImagePickerControllerCameraDevice cameraDevice; UIImagePickerControllerCameraFlashMode cameraFlashMode; + UIImagePickerControllerQualityType videoQuality; BOOL showsZBarControls, tracksSymbols, enableCache; ZBarHelpController *helpController; @@ -105,6 +106,7 @@ @property(nonatomic) UIImagePickerControllerCameraDevice cameraDevice; @property(nonatomic) UIImagePickerControllerCameraFlashMode cameraFlashMode; @property(nonatomic) UIImagePickerControllerCameraCaptureMode cameraCaptureMode; +@property(nonatomic) UIImagePickerControllerQualityType videoQuality; // direct access to the ZBarReaderView @property (nonatomic, readonly) ZBarReaderView *readerView; diff --git a/iphone/res/ZBarSDK-Info.plist b/iphone/res/ZBarSDK-Info.plist index bcfbde89..d3aa694c 100644 --- a/iphone/res/ZBarSDK-Info.plist +++ b/iphone/res/ZBarSDK-Info.plist @@ -7,7 +7,7 @@ CFBundleName ZBarSDK CFBundleVersion - 1.1.1 + 1.1.3 CFBundleSignature ???? NSHumanReadableCopyright