[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