2 * Copyright 2009 Jeff Verkoeyen
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #import "ZXingWidgetController.h"
19 #import "NSString+HTML.h"
20 #import "ResultParser.h"
21 #import "ParsedResult.h"
22 #import "ResultAction.h"
23 #include <sys/types.h>
24 #include <sys/sysctl.h>
26 #define CAMERA_SCALAR 1.12412 // scalar = (480 / (2048 / 480))
27 #define FIRST_TAKE_DELAY 1.0
29 CGImageRef UIGetScreenImage();
31 @implementation ZXingWidgetController
32 @synthesize result, actions, showCancel, delegate;
34 - (id)initWithDelegate:(id<ZXingDelegate>)scanDelegate {
35 if (self = [super init]) {
36 [self setDelegate:scanDelegate];
38 self.wantsFullScreenLayout = YES;
39 self.sourceType = UIImagePickerControllerSourceTypeCamera;
40 float zoomFactor = CAMERA_SCALAR;
41 if ([self fixedFocus]) {
44 self.cameraViewTransform = CGAffineTransformScale(
45 self.cameraViewTransform, zoomFactor, zoomFactor);
46 overlayView = [[OverlayView alloc] initWithCancelEnabled:showCancel frame:[UIScreen mainScreen].bounds];
47 [overlayView setDelegate:self];
48 self.sourceType = UIImagePickerControllerSourceTypeCamera;
49 self.showsCameraControls = NO;
50 self.cameraOverlayView = overlayView;
51 self.allowsEditing = NO; // [[NSUserDefaults standardUserDefaults] boolForKey:@"allowEditing"];
58 AudioServicesDisposeSystemSoundID(beepSound);
59 [overlayView dealloc];
64 NSLog(@"cancelled called in ZXingWidgetController");
66 if (delegate != nil) {
71 - (NSString *)getPlatform {
73 sysctlbyname("hw.machine", NULL, &size, NULL, 0);
74 char *machine = malloc(size);
75 sysctlbyname("hw.machine", machine, &size, NULL, 0);
76 NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
82 NSString *platform = [self getPlatform];
83 if ([platform isEqualToString:@"iPhone1,1"] ||
84 [platform isEqualToString:@"iPhone1,2"]) return true;
90 NSBundle *mainBundle = [NSBundle mainBundle];
91 OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:[mainBundle pathForResource:@"beep-beep" ofType:@"caf"] isDirectory:NO], &beepSound);
92 if (error != kAudioServicesNoError) {
93 NSLog(@"Problem loading nearSound.caf");
97 - (void)viewDidAppear:(BOOL)animated {
98 [super viewDidAppear:animated];
99 [overlayView setPoints:nil];
100 wasCancelled = false;
101 [NSTimer scheduledTimerWithTimeInterval: FIRST_TAKE_DELAY
103 selector: @selector(takePicture:)
108 - (void)takePicture:(NSTimer*)theTimer {
109 CGImageRef capture = UIGetScreenImage();
110 UIImage *scrn = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(capture, [overlayView cropRect])];
111 Decoder *d = [[Decoder alloc] init];
113 CGRect cropRect = overlayView.cropRect;
114 cropRect.origin.x = 0.0;
115 cropRect.origin.y = 0.0;
116 NSLog(@"crop rect %f, %f, %f, %f", cropRect.origin.x, cropRect.origin.y, cropRect.size.width, cropRect.size.height);
117 [d decodeImage:scrn cropRect:cropRect];
120 // DecoderDelegate methods
122 - (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset{
123 NSLog(@"DecoderViewController MessageWhileDecodingWithDimensions: Decoding image (%.0fx%.0f) ...", image.size.width, image.size.height);
126 - (void)decoder:(Decoder *)decoder
127 decodingImage:(UIImage *)image
128 usingSubset:(UIImage *)subset
129 progress:(NSString *)message {
130 NSLog(@"decoding image %@", message);
133 - (void)presentResultForString:(NSString *)resultString {
134 NSLog(@"in presentResultForString()");
135 self.result = [ResultParser parsedResultForString:resultString];
136 AudioServicesPlaySystemSound(beepSound);
138 NSLog(@"result string = %@", resultString);
139 NSLog(@"result has %d actions", actions ? 0 : actions.count);
141 // [self updateToolbar];
144 - (void)presentResultPoints:(NSArray *)resultPoints
145 forImage:(UIImage *)image
146 usingSubset:(UIImage *)subset {
147 // simply add the points to the image view
148 NSLog(@"got points for display");
149 [overlayView setPoints:resultPoints];
152 - (void)decoder:(Decoder *)decoder didDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset withResult:(TwoDDecoderResult *)twoDResult {
153 // [self presentResultForString:twoDResult.text];
154 NSLog(@"decoded image!!");
155 [self presentResultPoints:[twoDResult points] forImage:image usingSubset:subset];
156 // now, in a selector, call the delegate to give this overlay time to show the points
157 [self performSelector:@selector(alertDelegate:) withObject:[[twoDResult text] copy] afterDelay:1.0];
158 decoder.delegate = nil;
162 - (void)alertDelegate:(id)text {
163 if (delegate != nil) {
164 [delegate scanResult:text];
168 - (void)decoder:(Decoder *)decoder failedToDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset reason:(NSString *)reason {
169 decoder.delegate = nil;
171 [overlayView setPoints:nil];
173 [self takePicture:nil];
175 //[self updateToolbar];