2014-06-13 4 views
5

Ich versuche, einen QR-Code-Generator für OS X zu machen, aber ich hatte keine Nachfolge bei der Herstellung eines QRCode, der bunter sein kann als die schwarzen und weiß, die ich bin mit dem CIQRCodeGenerator für die CIImage Filter, wie ich diese Arbeit machen würde ich einen Beispielcode haben, die ich in meiner App implementiert haben: -Wie ändern Sie die Vorder- und Vordergrundfarbe eines CIFilter CIQRCodeGenerator Filters

+ (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 kann mir jemand in die richtige Richtung bitte.

Antwort

4

CIQRCodeGenerator erzeugt nur QR-Codes in Schwarz-Weiß, aber Sie können das resultierende Bild einfach in ein anderes Farbschema umwandeln.

eine Instanz des CIFalseColor Filter erstellen, legen Sie die inputImage zum outputImage von Ihrem Generator und seine inputColor0 und inputColor1 zu den Farben, die Sie anstelle von Schwarz und Weiß verwendet werden sollen. Zeichnen Sie dann den falschen Farbfilter outputImage in Ihrem CG-Kontext.

Sie könnten auch den Filter CIMaskToAlpha verwenden, um entweder das Schwarz oder Weiß im QR-Code-Bild transparent zu machen; dann kannst du es auf jede Hintergrundfarbe setzen. (Nur tun Sie es nicht auf zu beschäftigt Hintergrund oder Menschen nicht in der Lage sein, es zu scannen.)

+0

im Erraten inputColor0 ist die Hintergrundfarbe und inputColor1 ist die Vordergrundfarbe –

10

Heres den Code, der nun funktioniert: -

+ (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]; 
} 
+0

Brilliant. Danke für das Posten. Ich hoffe, es macht Ihnen nichts aus, wenn ich diese Methode in meiner Mac App verwende. Oh, vielleicht ist es meine Naivität, aber sollte nicht skaliertes Bild freigegeben werden, bevor du das letzte NSMage zurückbringst? –

+0

Ihre Begrüßung Diese grundlegenden Dinge müssen im Internet veröffentlicht werden, damit mehr Menschen über diese komplexen Methoden wie Filter wie QR-Codes lernen können. Die Methode funktioniert immer noch, ohne das skalierbare Image, das für mich stabil genug ist. –

Verwandte Themen