- (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]];
}
self.subsetImage = [UIImage imageWithCGImage:subsetImageRef];
// for debug purposes.
- UIImageWriteToSavedPhotosAlbum(self.subsetImage, nil, nil, nil);
+// UIImageWriteToSavedPhotosAlbum(self.subsetImage, nil, nil, nil);
CGImageRelease(subsetImageRef);
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 {
@synchronized(self) {
formatReaders = [[sFormatReaders copy] autorelease];
- NSLog(@"readers : %d",[formatReaders count]);
}
return formatReaders;
}
+ (void)load {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSLog(@"MultiFormatReader: load called");
[FormatReader registerFormatReader:[[[self alloc] init] autorelease]];
[pool drain];
}
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;
@implementation OverlayView
-@synthesize delegate;
+@synthesize delegate, oneDMode;
@synthesize points = _points;
//@synthesize image;
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];
}
imageView = nil;
[_points release];
_points = nil;
-
+ [cancelButton release];
[super dealloc];
}
[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];
+ }
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (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);
+ }
}
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;
#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;
- (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");
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];
self.result = [ResultParser parsedResultForString:resultString];
if (beepSound != -1) {
- NSLog(@"about to play beep... trying...");
AudioServicesPlaySystemSound(beepSound);
}
#ifdef DEBUG