2014-06-13 15 views
5

Sto provando a creare un generatore di codice QR per OS X ma non ho avuto la successione nel creare un QRCode che può essere più colorato che il nero e quelle bianche sto utilizzando il CIQRCodeGenerator per i filtri CIImage come potrei fare questo lavoro ho un codice di esempio che ho implementato nel mio app: -Come si modifica il colore di sfondo e di primo piano di un filtro CIQRCodeGenerator CIFilter

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

Così qualcuno mi può punto nella giusta direzione per favore.

risposta

4

CIQRCodeGenerator genera solo codici QR in bianco e nero, ma è possibile trasformare facilmente l'immagine risultante in un'altra combinazione di colori.

Creare un'istanza del filtro CIFalseColor, impostare la sua inputImage al outputImage dal generatore, e la sua inputColor0 e inputColor1 ai colori che si desidera utilizzare al posto del bianco e nero. Quindi disegna il filtro di colore falso outputImage nel tuo contesto CG.

Si potrebbe anche considerare l'utilizzo del filtro CIMaskToAlpha per rendere trasparente il nero o il bianco dell'immagine del codice QR; allora sarai in grado di metterlo in cima a qualsiasi colore di sfondo. (Basta non mettere su uno sfondo troppo occupato o persone non saranno in grado di eseguire la scansione.)

+0

Im Guessing inputColor0 è lo sfondo di colore e inputColor1 è il colore di primo piano –

10

Heres il codice che funziona ora: -

+ (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

brillante. Grazie per aver postato questo. Spero non ti dispiaccia se utilizzo questo metodo nella mia app Mac. Oh, forse è la mia ingenuità, ma non dovrebbe essere ridimensionato. L'immagine dovrebbe essere rilasciata prima di restituire l'ultimo NSImage? –

+0

Il tuo benvenuto Queste cose di base devono essere esposte a Internet in modo che più persone possano apprendere su questi metodi complessi come i filtri come i codici QR. Il metodo funziona ancora senza ridimensionare l'immagine che viene rilasciata è abbastanza stabile per me. –