Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you change the Back and Foreground Color of a CIFilter CIQRCodeGenerator Filter

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.

like image 498
Ash-Bash32 Avatar asked Jun 13 '14 16:06

Ash-Bash32


3 Answers

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)
}
like image 147
user3015717 Avatar answered Oct 16 '22 14:10

user3015717


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];
}
like image 23
Ash-Bash32 Avatar answered Oct 16 '22 15:10

Ash-Bash32


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.)

like image 9
rickster Avatar answered Oct 16 '22 14:10

rickster