diff --git a/iphone/ScanTest/Classes/RootViewController.m b/iphone/ScanTest/Classes/RootViewController.m index d852d7f63..48516266b 100644 --- a/iphone/ScanTest/Classes/RootViewController.m +++ b/iphone/ScanTest/Classes/RootViewController.m @@ -18,7 +18,10 @@ - (void)viewDidLoad { [super viewDidLoad]; [self setTitle:@"ZXing"]; - scanController = [[ZXingWidgetController alloc] initWithDelegate:self]; + scanController = [ZXingWidgetController alloc]; + [scanController setOneDMode:false]; + [scanController setShowCancel:true]; + scanController = [scanController initWithDelegate:self]; NSBundle *mainBundle = [NSBundle mainBundle]; [scanController setSoundToPlay:[[NSURL fileURLWithPath:[mainBundle pathForResource:@"beep-beep" ofType:@"aiff"] isDirectory:NO] retain]]; } diff --git a/iphone/ZXingWidget/Decoder.mm b/iphone/ZXingWidget/Decoder.mm index e70a685ae..55d927ae0 100644 --- a/iphone/ZXingWidget/Decoder.mm +++ b/iphone/ZXingWidget/Decoder.mm @@ -133,7 +133,7 @@ using namespace zxing; self.subsetImage = [UIImage imageWithCGImage:subsetImageRef]; // for debug purposes. - UIImageWriteToSavedPhotosAlbum(self.subsetImage, nil, nil, nil); +// UIImageWriteToSavedPhotosAlbum(self.subsetImage, nil, nil, nil); CGImageRelease(subsetImageRef); @@ -161,7 +161,7 @@ using namespace zxing; TwoDDecoderResult *decoderResult = nil; #ifdef TRY_ROTATIONS - for (int i = 0; !decoderResult && i < 4; i++) {` + for (int i = 0; !decoderResult && i < 4; i++) { #endif for (FormatReader *reader in formatReaders) { try { diff --git a/iphone/ZXingWidget/FormatReader.mm b/iphone/ZXingWidget/FormatReader.mm index a1294d824..74d5e2109 100644 --- a/iphone/ZXingWidget/FormatReader.mm +++ b/iphone/ZXingWidget/FormatReader.mm @@ -40,7 +40,6 @@ static NSMutableSet *sFormatReaders = nil; @synchronized(self) { formatReaders = [[sFormatReaders copy] autorelease]; - NSLog(@"readers : %d",[formatReaders count]); } return formatReaders; } diff --git a/iphone/ZXingWidget/MultiFormatReader.mm b/iphone/ZXingWidget/MultiFormatReader.mm index 3517e37be..a1b8bf701 100644 --- a/iphone/ZXingWidget/MultiFormatReader.mm +++ b/iphone/ZXingWidget/MultiFormatReader.mm @@ -28,7 +28,6 @@ + (void)load { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSLog(@"MultiFormatReader: load called"); [FormatReader registerFormatReader:[[[self alloc] init] autorelease]]; [pool drain]; } diff --git a/iphone/ZXingWidget/OverlayView.h b/iphone/ZXingWidget/OverlayView.h index f8436b10f..019ee1ef8 100755 --- a/iphone/ZXingWidget/OverlayView.h +++ b/iphone/ZXingWidget/OverlayView.h @@ -23,11 +23,13 @@ NSArray *_points; UIButton *cancelButton; id delegate; + BOOL oneDMode; } //@property (nonatomic, retain) UIImage* image; @property (nonatomic, retain) NSArray* points; @property (nonatomic, assign) id delegate; +@property (nonatomic, assign) BOOL oneDMode; - (id)initWithCancelEnabled:(BOOL)cancelEnabled frame:(CGRect)frame; diff --git a/iphone/ZXingWidget/OverlayView.m b/iphone/ZXingWidget/OverlayView.m index 35617670b..27ebd44cf 100755 --- a/iphone/ZXingWidget/OverlayView.m +++ b/iphone/ZXingWidget/OverlayView.m @@ -20,7 +20,7 @@ static const CGFloat kPadding = 10; @implementation OverlayView -@synthesize delegate; +@synthesize delegate, oneDMode; @synthesize points = _points; //@synthesize image; @@ -33,7 +33,14 @@ static const CGFloat kPadding = 10; if (cancelEnabled) { cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [cancelButton setTitle:@"Cancel" forState:UIControlStateNormal]; - [cancelButton setFrame:CGRectMake(95, 420, 130, 45)]; + if (oneDMode) { + [cancelButton setTransform:CGAffineTransformMakeRotation(M_PI/2)]; + [cancelButton setFrame:CGRectMake(20, 175, 45, 130)]; + } + else { + [cancelButton setFrame:CGRectMake(95, 420, 130, 45)]; + } + [cancelButton addTarget:self action:@selector(cancel:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:cancelButton]; } @@ -53,7 +60,7 @@ static const CGFloat kPadding = 10; imageView = nil; [_points release]; _points = nil; - + [cancelButton release]; [super dealloc]; } @@ -86,28 +93,57 @@ static const CGFloat kPadding = 10; [self drawRect:cropRect inContext:c]; // CGContextSetStrokeColor(c, white); - char *text = "Place a barcode inside the"; - char *text2 = "viewfinder rectangle to scan it."; // CGContextSetStrokeColor(c, white); CGContextSaveGState(c); - CGContextSelectFont(c, "Helvetica", 18, kCGEncodingMacRoman); - CGContextScaleCTM(c, -1.0, 1.0); - CGContextRotateCTM(c, 3.1415); - CGContextShowTextAtPoint(c, 48.0, -45.0, text, 26); - CGContextShowTextAtPoint(c, 33.0, -70.0, text2, 32); + if (oneDMode) { + char *text = "Place a red line over the bar code to be scanned."; + CGContextSelectFont(c, "Helvetica", 15, kCGEncodingMacRoman); + CGContextScaleCTM(c, -1.0, 1.0); + CGContextRotateCTM(c, M_PI/2); + CGContextShowTextAtPoint(c, 74.0, 285.0, text, 49); + } + else { + char *text = "Place a barcode inside the"; + char *text2 = "viewfinder rectangle to scan it."; + CGContextSelectFont(c, "Helvetica", 18, kCGEncodingMacRoman); + CGContextScaleCTM(c, -1.0, 1.0); + CGContextRotateCTM(c, M_PI); + CGContextShowTextAtPoint(c, 48.0, -45.0, text, 26); + CGContextShowTextAtPoint(c, 33.0, -70.0, text2, 32); + } CGContextRestoreGState(c); + int offset = rect.size.width / 2; + if (oneDMode) { + CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f}; + CGContextSetStrokeColor(c, red); + CGContextSetFillColor(c, red); + CGContextBeginPath(c); + // CGContextMoveToPoint(c, rect.origin.x + kPadding, rect.origin.y + offset); + // CGContextAddLineToPoint(c, rect.origin.x + rect.size.width - kPadding, rect.origin.y + offset); + CGContextMoveToPoint(c, rect.origin.x + offset, rect.origin.y + kPadding); + CGContextAddLineToPoint(c, rect.origin.x + offset, rect.origin.y + rect.size.height - kPadding); + CGContextStrokePath(c); + } if( nil != _points ) { CGFloat blue[4] = {0.0f, 1.0f, 0.0f, 1.0f}; CGContextSetStrokeColor(c, blue); CGContextSetFillColor(c, blue); - CGRect smallSquare = CGRectMake(0, 0, 10, 10); - for( NSValue* value in _points ) { - CGPoint point = [value CGPointValue]; - NSLog(@"drawing point at %f, %f", point.x, point.y); - smallSquare.origin = CGPointMake( - cropRect.origin.x + point.x - smallSquare.size.width / 2, - cropRect.origin.y + point.y - smallSquare.size.height / 2); - [self drawRect:smallSquare inContext:c]; + if (oneDMode) { + CGPoint val1 = [[_points objectAtIndex:0] CGPointValue]; + CGPoint val2 = [[_points objectAtIndex:1] CGPointValue]; + CGContextMoveToPoint(c, offset, val1.x); + CGContextAddLineToPoint(c, offset, val2.x); + CGContextStrokePath(c); + } + else { + CGRect smallSquare = CGRectMake(0, 0, 10, 10); + for( NSValue* value in _points ) { + CGPoint point = [value CGPointValue]; + smallSquare.origin = CGPointMake( + cropRect.origin.x + point.x - smallSquare.size.width / 2, + cropRect.origin.y + point.y - smallSquare.size.height / 2); + [self drawRect:smallSquare inContext:c]; + } } } } @@ -145,8 +181,13 @@ static const CGFloat kPadding = 10; //////////////////////////////////////////////////////////////////////////////////////////////////// - (CGRect) cropRect { CGFloat rectSize = self.frame.size.width - kPadding * 2; - - return CGRectMake(kPadding, (self.frame.size.height - rectSize) / 2, rectSize, rectSize); + if (!oneDMode) { + return CGRectMake(kPadding, (self.frame.size.height - rectSize) / 2, rectSize, rectSize); + } + else { + CGFloat rectSize2 = self.frame.size.height - kPadding * 2; + return CGRectMake(kPadding, kPadding, rectSize, rectSize2); + } } diff --git a/iphone/ZXingWidget/ZXingWidgetController.h b/iphone/ZXingWidget/ZXingWidgetController.h index 6955d3453..5a0cb0c54 100755 --- a/iphone/ZXingWidget/ZXingWidgetController.h +++ b/iphone/ZXingWidget/ZXingWidgetController.h @@ -31,11 +31,13 @@ NSURL *soundToPlay; id delegate; BOOL wasCancelled; + BOOL oneDMode; } @property (nonatomic, assign) id delegate; @property (nonatomic, assign) BOOL showCancel; @property (nonatomic, assign) NSURL *soundToPlay; +@property (nonatomic, assign) BOOL oneDMode; @property (nonatomic, retain) ParsedResult *result; @property (nonatomic, retain) NSArray *actions; diff --git a/iphone/ZXingWidget/ZXingWidgetController.m b/iphone/ZXingWidget/ZXingWidgetController.m index adfc11753..3f709e388 100755 --- a/iphone/ZXingWidget/ZXingWidgetController.m +++ b/iphone/ZXingWidget/ZXingWidgetController.m @@ -22,29 +22,32 @@ #import "ResultAction.h" #include #include +#include "UKImage.h" #define CAMERA_SCALAR 1.12412 // scalar = (480 / (2048 / 480)) #define FIRST_TAKE_DELAY 1.0 +#define ONE_D_BAND_HEIGHT 10.0 CGImageRef UIGetScreenImage(); @implementation ZXingWidgetController -@synthesize result, actions, showCancel, delegate, soundToPlay; +@synthesize result, actions, showCancel, delegate, soundToPlay, oneDMode; - (id)initWithDelegate:(id)scanDelegate { if (self = [super init]) { [self setDelegate:scanDelegate]; - showCancel = true; beepSound = -1; self.wantsFullScreenLayout = YES; self.sourceType = UIImagePickerControllerSourceTypeCamera; float zoomFactor = CAMERA_SCALAR; if ([self fixedFocus]) { - zoomFactor *= 1.5; + zoomFactor *= 2.0; } self.cameraViewTransform = CGAffineTransformScale( self.cameraViewTransform, zoomFactor, zoomFactor); - overlayView = [[OverlayView alloc] initWithCancelEnabled:showCancel frame:[UIScreen mainScreen].bounds]; + overlayView = [OverlayView alloc]; + [overlayView setOneDMode:oneDMode]; + overlayView = [overlayView initWithCancelEnabled:showCancel frame:[UIScreen mainScreen].bounds]; [overlayView setDelegate:self]; self.sourceType = UIImagePickerControllerSourceTypeCamera; self.showsCameraControls = NO; @@ -90,9 +93,7 @@ CGImageRef UIGetScreenImage(); - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - NSLog(@"should load sound"); if ([self soundToPlay] != nil) { - NSLog(@"will try to load sound"); OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)[self soundToPlay], &beepSound); if (error != kAudioServicesNoError) { NSLog(@"Problem loading nearSound.caf"); @@ -111,12 +112,104 @@ CGImageRef UIGetScreenImage(); repeats: NO]; } +- (CGImageRef)CGImageRotated90:(CGImageRef)imgRef +{ + CGFloat angleInRadians = -90 * (M_PI / 180); + CGFloat width = CGImageGetWidth(imgRef); + CGFloat height = CGImageGetHeight(imgRef); + + CGRect imgRect = CGRectMake(0, 0, width, height); + CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians); + CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform); + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef bmContext = CGBitmapContextCreate(NULL, + rotatedRect.size.width, + rotatedRect.size.height, + 8, + 0, + colorSpace, + kCGImageAlphaPremultipliedFirst); + CGContextSetAllowsAntialiasing(bmContext, FALSE); + CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone); + CGColorSpaceRelease(colorSpace); +// CGContextTranslateCTM(bmContext, +// +(rotatedRect.size.width/2), +// +(rotatedRect.size.height/2)); + CGContextScaleCTM(bmContext, rotatedRect.size.width/rotatedRect.size.height, 1.0); + CGContextTranslateCTM(bmContext, 0.0, rotatedRect.size.height); + CGContextRotateCTM(bmContext, angleInRadians); +// CGContextTranslateCTM(bmContext, +// -(rotatedRect.size.width/2), +// -(rotatedRect.size.height/2)); + CGContextDrawImage(bmContext, CGRectMake(0, 0, + rotatedRect.size.width, + rotatedRect.size.height), + imgRef); + + CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext); + CFRelease(bmContext); + [(id)rotatedImage autorelease]; + + return rotatedImage; +} + +- (CGImageRef)CGImageRotated180:(CGImageRef)imgRef +{ + CGFloat angleInRadians = M_PI; + CGFloat width = CGImageGetWidth(imgRef); + CGFloat height = CGImageGetHeight(imgRef); + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef bmContext = CGBitmapContextCreate(NULL, + width, + height, + 8, + 0, + colorSpace, + kCGImageAlphaPremultipliedFirst); + CGContextSetAllowsAntialiasing(bmContext, FALSE); + CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone); + CGColorSpaceRelease(colorSpace); + CGContextTranslateCTM(bmContext, + +(width/2), + +(height/2)); + CGContextRotateCTM(bmContext, angleInRadians); + CGContextTranslateCTM(bmContext, + -(width/2), + -(height/2)); + CGContextDrawImage(bmContext, CGRectMake(0, 0, width, height), imgRef); + + CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext); + CFRelease(bmContext); + [(id)rotatedImage autorelease]; + + return rotatedImage; +} + - (void)takePicture:(NSTimer*)theTimer { CGImageRef capture = UIGetScreenImage(); - UIImage *scrn = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(capture, [overlayView cropRect])]; + CGRect cropRect = [overlayView cropRect]; + if (oneDMode) { + // let's just give the decoder a vertical band right above the red line + cropRect.origin.x = cropRect.origin.x + (cropRect.size.width / 2) - (ONE_D_BAND_HEIGHT + 1); + cropRect.size.width = ONE_D_BAND_HEIGHT; + // do a rotate + CGImageRef croppedImg = CGImageCreateWithImageInRect(capture, cropRect); + CGImageRelease(capture); + capture = [self CGImageRotated90:croppedImg]; + capture = [self CGImageRotated180:capture]; +// UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:capture], nil, nil, nil); + CGImageRelease(croppedImg); + cropRect.origin.x = 0.0; + cropRect.origin.y = 0.0; + cropRect.size.width = CGImageGetWidth(capture); + cropRect.size.height = CGImageGetHeight(capture); + } + + UIImage *scrn = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(capture, cropRect)]; Decoder *d = [[Decoder alloc] init]; d.delegate = self; - CGRect cropRect = overlayView.cropRect; cropRect.origin.x = 0.0; cropRect.origin.y = 0.0; [d decodeImage:scrn cropRect:cropRect]; @@ -140,7 +233,6 @@ CGImageRef UIGetScreenImage(); self.result = [ResultParser parsedResultForString:resultString]; if (beepSound != -1) { - NSLog(@"about to play beep... trying..."); AudioServicesPlaySystemSound(beepSound); } #ifdef DEBUG