[SCM] Multi-format 1D/2D barcode image processing library branch, upstream, updated. 24d4480bc48cf9eabf7b2bd2f528248b0e458809

dkavanagh dkavanagh at 59b500cc-1b3d-0410-9834-0bbf25fbcc57
Wed Aug 4 01:31:38 UTC 2010


The following commit has been merged in the upstream branch:
commit 22a42379f73fc380fe4b67fe45881f14673a44a9
Author: dkavanagh <dkavanagh at 59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Date:   Wed May 19 01:52:38 2010 +0000

    Did a special OneD mode for scanning UPC codes and the like. It uses a landscape scan UI with a red line (and green line highlighting the decoded area). Must set it explictly in the ScanTest - where the ZXingWidget is created.
    
    
    git-svn-id: http://zxing.googlecode.com/svn/trunk@1370 59b500cc-1b3d-0410-9834-0bbf25fbcc57

diff --git a/iphone/ScanTest/Classes/RootViewController.m b/iphone/ScanTest/Classes/RootViewController.m
index d852d7f..4851626 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 e70a685..55d927a 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 a1294d8..74d5e21 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 3517e37..a1b8bf7 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 f8436b1..019ee1e 100755
--- a/iphone/ZXingWidget/OverlayView.h
+++ b/iphone/ZXingWidget/OverlayView.h
@@ -23,11 +23,13 @@
 	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;
+ at 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 3561767..27ebd44 100755
--- a/iphone/ZXingWidget/OverlayView.m
+++ b/iphone/ZXingWidget/OverlayView.m
@@ -20,7 +20,7 @@ static const CGFloat kPadding = 10;
 
 @implementation OverlayView
 
- at synthesize delegate;
+ at 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 6955d34..5a0cb0c 100755
--- a/iphone/ZXingWidget/ZXingWidgetController.h
+++ b/iphone/ZXingWidget/ZXingWidgetController.h
@@ -31,11 +31,13 @@
 	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;
+ at 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 adfc117..3f709e3 100755
--- a/iphone/ZXingWidget/ZXingWidgetController.m
+++ b/iphone/ZXingWidget/ZXingWidgetController.m
@@ -22,29 +22,32 @@
 #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
- at synthesize result, actions, showCancel, delegate, soundToPlay;
+ at 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

-- 
Multi-format 1D/2D barcode image processing library



More information about the Pkg-google-commits mailing list