Did a special OneD mode for scanning UPC codes and the like. It uses a landscape...
authordkavanagh <dkavanagh@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Wed, 19 May 2010 01:52:38 +0000 (01:52 +0000)
committerdkavanagh <dkavanagh@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Wed, 19 May 2010 01:52:38 +0000 (01:52 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@1370 59b500cc-1b3d-0410-9834-0bbf25fbcc57

iphone/ScanTest/Classes/RootViewController.m
iphone/ZXingWidget/Decoder.mm
iphone/ZXingWidget/FormatReader.mm
iphone/ZXingWidget/MultiFormatReader.mm
iphone/ZXingWidget/OverlayView.h
iphone/ZXingWidget/OverlayView.m
iphone/ZXingWidget/ZXingWidgetController.h
iphone/ZXingWidget/ZXingWidgetController.m

index d852d7f..4851626 100644 (file)
 - (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]];
 }
index e70a685..55d927a 100644 (file)
@@ -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 {
index a1294d8..74d5e21 100644 (file)
@@ -40,7 +40,6 @@ static NSMutableSet *sFormatReaders = nil;
   @synchronized(self) {
 
     formatReaders = [[sFormatReaders copy] autorelease];
-         NSLog(@"readers : %d",[formatReaders count]);
   }
   return formatReaders;
 }
index 3517e37..a1b8bf7 100644 (file)
@@ -28,7 +28,6 @@
 
 + (void)load {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-       NSLog(@"MultiFormatReader: load called");
   [FormatReader registerFormatReader:[[[self alloc] init] autorelease]];
   [pool drain];
 }
index f8436b1..019ee1e 100755 (executable)
        NSArray *_points;
        UIButton *cancelButton;
        id<CancelDelegate> delegate;
+       BOOL oneDMode;
 }
 
 //@property (nonatomic, retain)   UIImage*  image;
 @property (nonatomic, retain) NSArray*  points;
 @property (nonatomic, assign) id<CancelDelegate> delegate;
+@property (nonatomic, assign) BOOL oneDMode;
 
 - (id)initWithCancelEnabled:(BOOL)cancelEnabled frame:(CGRect)frame;
 
index 3561767..27ebd44 100755 (executable)
@@ -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);             
+       }
 }
 
 
index 6955d34..5a0cb0c 100755 (executable)
        NSURL *soundToPlay;
        id<ZXingDelegate> delegate;
        BOOL wasCancelled;
+       BOOL oneDMode;
 }
 
 @property (nonatomic, assign) id<ZXingDelegate> 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;
 
index adfc117..3f709e3 100755 (executable)
 #import "ResultAction.h"
 #include <sys/types.h>
 #include <sys/sysctl.h>
+#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<ZXingDelegate>)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