I'm trying to make a QR Code Generator for OS X but i haven't had succession in making a QRCode that can be more colourful that the black and white ones I'm using the CIQRCodeGenerator for the CIImage Filters how would i make this work I've got a sample code that I've implemented into my app :-
+ (NSImage *)createQRImageForString:(NSString *)string size:(CGSize)size {
// Setup the QR filter with our string
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@"inputMessage"];
CIImage *image = [filter valueForKey:@"outputImage"];
// Calculate the size of the generated image and the scale for the desired image size
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size.width / CGRectGetWidth(extent), size.height / CGRectGetHeight(extent));
// Since CoreImage nicely interpolates, we need to create a bitmap image that we'll draw into
// a bitmap context at the desired size;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 256*4, cs, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
#if TARGET_OS_IPHONE
CIContext *context = [CIContext contextWithOptions:nil];
#else
CIContext *context = [CIContext contextWithCGContext:bitmapRef options:nil];
#endif
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// Create an image with the contents of our bitmap
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
// Cleanup
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [[NSImage alloc] initWithCGImage:scaledImage size:NSZeroSize];
}
So can someone Point me in the right direction please.
Here's an example in swift (for the googlers)
func qrCode(from string: String) -> UIImage? {
let data = string.data(using: .ascii)
// Generate the code image with CIFilter
guard let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
filter.setValue(data, forKey: "inputMessage")
// Scale it up (because it is generated as a tiny image)
let scale = UIScreen.main.scale
let transform = CGAffineTransform(scaleX: scale, y: scale)
guard let output = filter.outputImage?.transformed(by: transform) else { return nil }
// Change the color using CIFilter
let colorParameters = [
"inputColor0": CIColor(color: UIColor.black), // Foreground
"inputColor1": CIColor(color: UIColor.clear) // Background
]
let colored = output.applyingFilter("CIFalseColor", parameters: colorParameters)
return UIImage(ciImage: colored)
}
Heres the Code that works Now :-
+ (NSImage *)createQRImageForString:(NSString *)string backgroundColor:(CIColor*)iBackgroundColor foregroundColor:(CIColor*)iForegroundColor size:(CGSize)size {
CIImage *image;
CIFilter *filter;
CIFilter *filterColor;
// Setup the QR filter with our string
filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@"inputMessage"];
image = [filter valueForKey:@"outputImage"];
filterColor = [CIFilter filterWithName:@"CIFalseColor" keysAndValues:@"inputImage", image, @"inputColor0", iForegroundColor, @"inputColor1", iBackgroundColor, nil];
//[filterColor setDefaults];
image = [filterColor valueForKey:@"outputImage"];
//image = [CIImage imageWithColor:[CIColor colorWithRed:1 green: 0 blue: 0]];
// Calculate the size of the generated image and the scale for the desired image size
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size.width / CGRectGetWidth(extent), size.height / CGRectGetHeight(extent));
// Since CoreImage nicely interpolates, we need to create a bitmap image that we'll draw into
// a bitmap context at the desired size;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 256*4, cs, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
#if TARGET_OS_IPHONE
CIContext *context = [CIContext contextWithOptions:nil];
#else
CIContext *context = [CIContext contextWithCGContext:bitmapRef options:nil];
#endif
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// Create an image with the contents of our bitmap
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
// Cleanup
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [[NSImage alloc] initWithCGImage:scaledImage size:NSZeroSize];
}
CIQRCodeGenerator
only generates QR codes in black and white, but you can easily transform the resulting image to another color scheme.
Create an instance of the CIFalseColor
filter, set its inputImage
to the outputImage
from your generator, and its inputColor0
and inputColor1
to the colors you want to use instead of black and white. Then draw the false color filter's outputImage
into your CG context.
You could also consider using the CIMaskToAlpha
filter to turn either the black or white in the QR code image to transparent; then you'll be able to put it on top of any background color. (Just don't put it on too busy a background or people won't be able to scan it.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With