@interface Decoder : NSObject {
UIImage *image;
+ CGRect cropRect;
UIImage *subsetImage;
unsigned char *subsetData;
size_t subsetWidth;
}
@property(nonatomic, retain) UIImage *image;
+@property(nonatomic, assign) CGRect cropRect;
@property(nonatomic, retain) UIImage *subsetImage;
@property(nonatomic, assign) unsigned char *subsetData;
@property(assign) size_t subsetWidth;
@property(nonatomic, assign) id<DecoderDelegate> delegate;
- (void) decodeImage:(UIImage *)image;
-- (void) decodeImage:(UIImage *)image cropRectangle:(CGRect)cropRect;
+- (void) decodeImage:(UIImage *)image cropRect:(CGRect)cropRect;
@end
@implementation Decoder
@synthesize image;
+@synthesize cropRect;
@synthesize subsetImage;
@synthesize subsetData;
@synthesize subsetWidth;
@synthesize delegate;
- (void)willDecodeImage {
- [self.delegate decoder:self willDecodeImage:self.image];
+ [self.delegate decoder:self willDecodeImage:self.image usingSubset:self.subsetImage];
}
- (void)progressDecodingImage:(NSString *)progress {
#define SUBSET_SIZE 320.0
- (void) prepareSubset {
- CGImageRef cgImage = self.image.CGImage;
- CGSize size = CGSizeMake(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage));
+ CGSize size = [image size];
#ifdef DEBUG
- NSLog(@"decoding: image is (%.1f x %.1f)", size.width, size.height);
+ NSLog(@"decoding: image is (%.1f x %.1f), cropRect is (%.1f,%.1f)x(%.1f,%.1f)", size.width, size.height,
+ cropRect.origin.x, cropRect.origin.y, cropRect.size.width, cropRect.size.height);
#endif
- float scale = fminf(1.0f, fmaxf(SUBSET_SIZE / size.width, SUBSET_SIZE / size.height));
- subsetWidth = size.width * scale;
- subsetHeight = size.height * scale;
+ float scale = fminf(1.0f, fmaxf(SUBSET_SIZE / cropRect.size.width, SUBSET_SIZE / cropRect.size.height));
+ CGPoint offset = CGPointMake(-cropRect.origin.x, -cropRect.origin.y);
+#ifdef DEBUG
+ NSLog(@" offset = (%.1f, %.1f), scale = %.3f", offset.x, offset.y, scale);
+#endif
+
+ subsetWidth = cropRect.size.width * scale;
+ subsetHeight = cropRect.size.height * scale;
subsetBytesPerRow = ((subsetWidth + 0xf) >> 4) << 4;
#ifdef DEBUG
CGColorSpaceRelease(grayColorSpace);
CGContextSetInterpolationQuality(ctx, kCGInterpolationNone);
CGContextSetAllowsAntialiasing(ctx, false);
+ // adjust the coordinate system
+ CGContextTranslateCTM(ctx, 0.0, subsetHeight);
+ CGContextScaleCTM(ctx, 1.0, -1.0);
#ifdef DEBUG
NSLog(@"created %dx%d bitmap context", subsetWidth, subsetHeight);
#endif
- CGRect rect = CGRectMake(0, 0, subsetWidth, subsetHeight);
+
+ UIGraphicsPushContext(ctx);
+ CGRect rect = CGRectMake(offset.x * scale, offset.y * scale, scale * size.width, scale * size.height);
+#ifdef DEBUG
+ NSLog(@"rect for image = (%.1f,%.1f)x(%.1f,%.1f)", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+#endif
+ [image drawInRect:rect];
+ UIGraphicsPopContext();
- CGContextDrawImage(ctx, rect, cgImage);
#ifdef DEBUG
NSLog(@"drew image into %d(%d)x%d bitmap context", subsetWidth, subsetBytesPerRow, subsetHeight);
#endif
}
- (void) decodeImage:(UIImage *)i {
- CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
- [self decodeImage:i cropRectangle:rect];
+ [self decodeImage:i cropRect:CGRectMake(0.0f, 0.0f, image.size.width, image.size.height)];
}
-- (void) decodeImage:(UIImage *)i cropRectangle:(CGRect)cropRect {
+- (void) decodeImage:(UIImage *)i cropRect:(CGRect)cr {
self.image = i;
- [self.delegate decoder:self willDecodeImage:i];
+ self.cropRect = cr;
[self prepareSubset];
+ [self.delegate decoder:self willDecodeImage:i usingSubset:self.subsetImage];
+
[self performSelectorOnMainThread:@selector(progressDecodingImage:)
withObject:NSLocalizedString(@"Decoder MessageWhileDecoding", @"Decoding ...")
@protocol DecoderDelegate
-- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image;
+- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset;
- (void)decoder:(Decoder *)decoder decodingImage:(UIImage *)image usingSubset:(UIImage *)subset progress:(NSString *)message;
- (void)decoder:(Decoder *)decoder didDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset withResult:(TwoDDecoderResult *)result;
- (void)decoder:(Decoder *)decoder failedToDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset reason:(NSString *)reason;
/* DecoderDelegate methods */
-- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image;
+- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset;
- (void)decoder:(Decoder *)decoder decodingImage:(UIImage *)image usingSubset:(UIImage *)subset progress:(NSString *) message;
- (void)decoder:(Decoder *)decoder didDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset withResult:(TwoDDecoderResult *)result;
- (void)pickAndDecodeFromSource:(UIImagePickerControllerSourceType) sourceType {
[self reset];
- \
+
// Create the Image Picker
if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
// DecoderDelegate methods
-- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image {
+- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset{
[self clearImageView];
- [self.imageView setImage:image];
+ [self.imageView setImage:subset];
[self showMessage:[NSString stringWithFormat:NSLocalizedString(@"DecoderViewController MessageWhileDecodingWithDimensions", @"Decoding image (%.0fx%.0f) ..."), image.size.width, image.size.height]
helpButton:NO];
}
editingInfo:(NSDictionary *)editingInfo
{
UIImage *imageToDecode = image;
+ CGSize size = [image size];
+ CGRect cropRect = CGRectMake(0.0, 0.0, size.width, size.height);
+
#ifdef DEBUG
- NSLog(@"picked image size = (%f, %f)", image.size.width, image.size.height);
+ NSLog(@"picked image size = (%f, %f)", size.width, size.height);
#endif
+ NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
+
if (editingInfo) {
UIImage *originalImage = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];
if (originalImage) {
#endif
NSValue *cropRectValue = [editingInfo objectForKey:UIImagePickerControllerCropRect];
if (cropRectValue) {
- CGRect cropRect = [cropRectValue CGRectValue];
+ cropRect = [cropRectValue CGRectValue];
#ifdef DEBUG
NSLog(@"crop rect = (%f, %f) x (%f, %f)", CGRectGetMinX(cropRect), CGRectGetMinY(cropRect), CGRectGetWidth(cropRect), CGRectGetHeight(cropRect));
#endif
- UIGraphicsBeginImageContext(cropRect.size);
-
- [originalImage drawAtPoint:CGPointMake(-CGRectGetMinX(cropRect),
- -CGRectGetMinY(cropRect))];
-
- imageToDecode = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
+ if (([picker sourceType] == UIImagePickerControllerSourceTypeSavedPhotosAlbum) &&
+ [@"2.1" isEqualToString:systemVersion]) {
+ // adjust crop rect to work around bug in iPhone OS 2.1 when selecting from the photo roll
+ cropRect.origin.x *= 2.5;
+ cropRect.origin.y *= 2.5;
+ cropRect.size.width *= 2.5;
+ cropRect.size.height *= 2.5;
+#ifdef DEBUG
+ NSLog(@"2.1-adjusted crop rect = (%f, %f) x (%f, %f)", CGRectGetMinX(cropRect), CGRectGetMinY(cropRect), CGRectGetWidth(cropRect), CGRectGetHeight(cropRect));
+#endif
+ }
+
+ imageToDecode = originalImage;
}
}
}
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[imageToDecode retain];
[picker release];
- [self.decoder decodeImage:imageToDecode];
+ [self.decoder decodeImage:imageToDecode cropRect:cropRect];
[imageToDecode release];
[self updateToolbar];
}
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Christian Brunschen";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = Barcodes;
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "3B103E1C-067D-4368-B6A0-6FDCFE7B0D47";
};
name = Debug;
};
GCC_PREFIX_HEADER = ZXing_Prefix.pch;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = Barcodes;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "6827259A-0073-4678-82F6-329E230F6801";
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "3B103E1C-067D-4368-B6A0-6FDCFE7B0D47";
};
name = Release;
};
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Christian Brunschen";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "3A1B16DE-FE88-44B7-B4AD-D409BB8F7DDD";
SDKROOT = iphoneos2.0;
};
name = "AdHoc Distribution";
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CODE_SIGN_ENTITLEMENTS = Entitlements.plist;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Christian Brunschen";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ZXing_Prefix.pch;
INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = Barcodes;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "6CDE626B-71E0-4E2A-BED0-DDE5BE24A701";
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "3A1B16DE-FE88-44B7-B4AD-D409BB8F7DDD";
};
name = "AdHoc Distribution";
};
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "F7E3CE9A-42BC-4860-A74F-B4D05A088442";
SDKROOT = macosx10.5;
};
name = Test;
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Christian Brunschen";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = DefaultProfileUuid;
SDKROOT = iphoneos2.0;
};
name = Distribution;
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CODE_SIGN_ENTITLEMENTS = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Christian Brunschen";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "F7E3CE9A-42BC-4860-A74F-B4D05A088442";
SDKROOT = iphoneos2.0;
};
name = Debug;
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = DefaultProfileUuid;
SDKROOT = iphoneos2.0;
};
name = Release;