diff --git a/QRCode.xcodeproj/project.pbxproj b/QRCode.xcodeproj/project.pbxproj index a2e0a8b..c104091 100644 --- a/QRCode.xcodeproj/project.pbxproj +++ b/QRCode.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 31693FC71F0939F8000F9231 /* redButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 31693FC61F0939F8000F9231 /* redButton.png */; }; 52DC9B6E188D65A300272042 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52DC9B6D188D65A300272042 /* Foundation.framework */; }; 52DC9B70188D65A300272042 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52DC9B6F188D65A300272042 /* CoreGraphics.framework */; }; 52DC9B72188D65A300272042 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52DC9B71188D65A300272042 /* UIKit.framework */; }; @@ -43,6 +44,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 31693FC61F0939F8000F9231 /* redButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = redButton.png; sourceTree = ""; }; 52DC9B6A188D65A300272042 /* QRCode.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QRCode.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52DC9B6D188D65A300272042 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 52DC9B6F188D65A300272042 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -180,6 +182,7 @@ isa = PBXGroup; children = ( 52DC9B9D188D660C00272042 /* Default-568h@2x.png */, + 31693FC61F0939F8000F9231 /* redButton.png */, 52DC9B9E188D660C00272042 /* Default@2x.png */, 52DC9B9F188D660C00272042 /* Icon.png */, ); @@ -298,6 +301,7 @@ 52DC9BA2188D660C00272042 /* Icon.png in Resources */, 52DC9B80188D65A300272042 /* Images.xcassets in Resources */, 52DC9BA0188D660C00272042 /* Default-568h@2x.png in Resources */, + 31693FC71F0939F8000F9231 /* redButton.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -522,6 +526,7 @@ 52DC9B98188D65A300272042 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 52DC9B99188D65A300272042 /* Build configuration list for PBXNativeTarget "QRCodeTests" */ = { isa = XCConfigurationList; @@ -530,6 +535,7 @@ 52DC9B9B188D65A300272042 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/QRCode/MDAppDelegate.m b/QRCode/MDAppDelegate.m index aedcfe0..352ff0d 100644 --- a/QRCode/MDAppDelegate.m +++ b/QRCode/MDAppDelegate.m @@ -35,7 +35,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( CGFloat imageSize = ceilf(viewController.view.bounds.size.width * 0.6f); UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(floorf(viewController.view.bounds.size.width * 0.5f - imageSize * 0.5f), floorf(viewController.view.bounds.size.height * 0.5f - imageSize * 0.5f), imageSize, imageSize)]; [viewController.view addSubview:imageView]; - imageView.image = [UIImage mdQRCodeForString:@"Hello, world!" size:imageView.bounds.size.width fillColor:[UIColor darkGrayColor]]; +// imageView.image = [UIImage mdQRCodeForString:@"Hello, world!" size:imageView.bounds.size.width fillColor:[UIColor darkGrayColor]]; + imageView.image = [UIImage mdQRCodeForString:@"Hello, world!" size:imageView.bounds.size.width fillImage:[UIImage imageNamed:@"redButton"]]; + self.window.rootViewController = viewController; return YES; } diff --git a/QRCode/QR/UIImage+MDQRCode.h b/QRCode/QR/UIImage+MDQRCode.h index 052b4e3..820d404 100644 --- a/QRCode/QR/UIImage+MDQRCode.h +++ b/QRCode/QR/UIImage+MDQRCode.h @@ -33,6 +33,7 @@ */ + (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)size; + (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)size fillColor:(UIColor *)fillColor; ++ (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)size fillImage:(UIImage *)fillImage; @end diff --git a/QRCode/QR/UIImage+MDQRCode.m b/QRCode/QR/UIImage+MDQRCode.m index 01d9dcf..6dd44c4 100644 --- a/QRCode/QR/UIImage+MDQRCode.m +++ b/QRCode/QR/UIImage+MDQRCode.m @@ -28,82 +28,106 @@ @implementation UIImage (MDQRCode) #pragma mark - private -+ (void)mdDrawQRCode:(QRcode *)code context:(CGContextRef)ctx size:(CGFloat)size fillColor:(UIColor *)fillColor { - int margin = 0; - unsigned char *data = code->data; - int width = code->width; - int totalWidth = width + margin * 2; - int imageSize = (int)floorf(size); - - // @todo - review float->int stuff - int pixelSize = imageSize / totalWidth; - if (imageSize % totalWidth) { - pixelSize = imageSize / width; - margin = (imageSize - width * pixelSize) / 2; - } - - CGRect rectDraw = CGRectMake(0.0f, 0.0f, pixelSize, pixelSize); - // draw - CGContextSetFillColorWithColor(ctx, fillColor.CGColor); - for(int i = 0; i < width; ++i) { - for(int j = 0; j < width; ++j) { - if(*data & 1) { - rectDraw.origin = CGPointMake(margin + j * pixelSize, margin + i * pixelSize); - CGContextAddRect(ctx, rectDraw); - } - ++data; - } - } - CGContextFillPath(ctx); ++ (void)mdDrawQRCode:(QRcode *)code context:(CGContextRef)ctx size:(CGFloat)size fillImage:(UIImage *)fillImage orFillColor:(UIColor *)fillColor { + int margin = 0; + unsigned char *data = code->data; + int width = code->width; + int totalWidth = width + margin * 2; + int imageSize = (int)floorf(size); + + // @todo - review float->int stuff + int pixelSize = imageSize / totalWidth; + if (imageSize % totalWidth) { + pixelSize = imageSize / width; + margin = (imageSize - width * pixelSize) / 2; + } + + CGRect rectDraw = CGRectMake(0.0f, 0.0f, pixelSize, pixelSize); + // draw + if (fillColor) { + CGContextSetFillColorWithColor(ctx, fillColor.CGColor); + } + + for(int i = 0; i < width; ++i) { + for(int j = 0; j < width; ++j) { + if(*data & 1) { + rectDraw.origin = CGPointMake(margin + j * pixelSize, margin + i * pixelSize); + if (fillColor) { + CGContextAddRect(ctx, rectDraw); + }else if (fillImage) { + UIGraphicsPushContext(ctx); + [fillImage drawInRect:rectDraw]; + UIGraphicsPopContext(); + } + } + ++data; + } + } + CGContextFillPath(ctx); +} + ++ (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)imageSize boxImage:(UIImage *)fillImage orFillColor:(UIColor *)fillColor{ + + + if (0 == [qrString length]) { + return nil; + } + + // generate QR + QRcode *code = QRcode_encodeString([qrString UTF8String], 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) { + return nil; + } + + CGFloat size = imageSize * [[UIScreen mainScreen] scale]; + if (code->width > size) { + printf("Image size is less than qr code size (%d)\n", code->width); + return nil; + } + + // create context + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + + // The constants for specifying the alpha channel information are declared with the CGImageAlphaInfo type but can be passed to this parameter safely. + + CGContextRef ctx = CGBitmapContextCreate(0, size, size, 8, size * 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast); + + CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(0, -size); + CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1, -1); + CGContextConcatCTM(ctx, CGAffineTransformConcat(translateTransform, scaleTransform)); + + // draw QR on this context + + [self mdDrawQRCode:code context:ctx size:size fillImage:fillImage orFillColor:fillColor]; + + + // get image + CGImageRef qrCGImage = CGBitmapContextCreateImage(ctx); + UIImage * qrImage = [UIImage imageWithCGImage:qrCGImage]; + + // free memory + CGContextRelease(ctx); + CGImageRelease(qrCGImage); + CGColorSpaceRelease(colorSpace); + QRcode_free(code); + return qrImage; + } #pragma mark - public + + (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)size { - return [self mdQRCodeForString:qrString size:size fillColor:[UIColor blackColor]]; + return [self mdQRCodeForString:qrString size:size fillColor:[UIColor blackColor]]; } + (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)imageSize fillColor:(UIColor *)fillColor { - if (0 == [qrString length]) { - return nil; - } - - // generate QR - QRcode *code = QRcode_encodeString([qrString UTF8String], 0, QR_ECLEVEL_L, QR_MODE_8, 1); - if (!code) { - return nil; - } - - CGFloat size = imageSize * [[UIScreen mainScreen] scale]; - if (code->width > size) { - printf("Image size is less than qr code size (%d)\n", code->width); - return nil; - } - - // create context - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - - // The constants for specifying the alpha channel information are declared with the CGImageAlphaInfo type but can be passed to this parameter safely. - - CGContextRef ctx = CGBitmapContextCreate(0, size, size, 8, size * 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast); - - CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(0, -size); - CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1, -1); - CGContextConcatCTM(ctx, CGAffineTransformConcat(translateTransform, scaleTransform)); - - // draw QR on this context - [self mdDrawQRCode:code context:ctx size:size fillColor:fillColor]; - - // get image - CGImageRef qrCGImage = CGBitmapContextCreateImage(ctx); - UIImage * qrImage = [UIImage imageWithCGImage:qrCGImage]; - - // free memory - CGContextRelease(ctx); - CGImageRelease(qrCGImage); - CGColorSpaceRelease(colorSpace); - QRcode_free(code); - return qrImage; + return [self mdQRCodeForString:qrString size:imageSize boxImage:nil orFillColor:fillColor]; + +} ++ (UIImage *)mdQRCodeForString:(NSString *)qrString size:(CGFloat)imageSize fillImage:(UIImage *)fillImage{ + return [self mdQRCodeForString:qrString size:imageSize boxImage:fillImage orFillColor:nil]; } + @end diff --git a/Resources/redButton.png b/Resources/redButton.png new file mode 100644 index 0000000..34bd32c Binary files /dev/null and b/Resources/redButton.png differ