2013-03-14 3 views
6

Ho bisogno di rendere UIBezierPaths senza anti-aliasing e quindi di salvarli come PNG per conservare le rappresentazioni complete dei pixel (per esempio, non lasciare che JPEG muck l'immagine). Ho provato a chiamare le funzioni CG di seguito appena prima di accarezzare UIBezierPaths, ma sembra che nessuno abbia alcun effetto sull'immagine di rendering risultante. I percorsi sono ancora renderizzati con anti-aliasing (cioè levigato).disabilita l'anti-aliasing per UIBezierPath

CGContextSetShouldAntialias(c, NO); 
CGContextSetAllowsAntialiasing(c, NO); 
CGContextSetInterpolationQuality(c, kCGInterpolationNone); 

Qualsiasi hit sarebbe molto apprezzato.

risposta

11

Quando uso queste opzioni, spegne l'antialiasing. A sinistra è con le opzioni predefinite. A destra, con le tue opzioni.

enter image description here

Questo è facile da controllare se si sta utilizzando una sottoclasse UIView. Questo è il mio drawRect:

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetShouldAntialias(context, NO); 

    [[UIColor redColor] setStroke]; 
    UIBezierPath *path = [self myPath]; 
    [path stroke]; 
} 

E per catturare lo schermo, da How to take a screenshot programmatically

- (void)captureScreen 
{ 
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) 
     UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale); 
    else 
     UIGraphicsBeginImageContext(self.window.bounds.size); 
    [self.window.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    NSData *data = UIImagePNGRepresentation(image); 
    [data writeToFile:[self screenShotFilename] atomically:YES]; 
} 

Se stai usando un CAShapeLayer, quindi non credo che si può controllare l'antialiasing sullo schermo, perché as the documentation says:

La forma verrà disegnata antialias, e, ove possibile, verrà mappata nello spazio schermo prima di essere rasterizzato per preservare i risoluzione ndependence. Tuttavia, alcuni tipi di operazioni di elaborazione delle immagini, come i filtri CoreImage, applicati al livello o ai relativi antenati possono forzare la rasterizzazione in uno spazio di coordinate locale.

Ma, a prescindere dal antialiasing sullo schermo, se si vuole avere l'istantanea dello schermo non essere antialias, è possibile inserire i tuoi CGContextSetShouldAntialias nel captureScreen di routine:

- (void)captureScreen 
{ 
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) 
     UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale); 
    else 
     UIGraphicsBeginImageContext(self.window.bounds.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetShouldAntialias(context, NO); 
    [self.window.layer renderInContext:context]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    NSData * data = UIImagePNGRepresentation(image); 
    [data writeToFile:[self screenShotFilename] atomically:YES]; 
} 
+0

Wow, @rob, grazie per una risposta così completa, ho imparato alcune cose nuove sulla linea :) – alonjr

+0

@Rob, potresti consigliarti perché l'anti-aliasing porta quello sfondo grigio (immagine a sinistra)? Grazie. – berec

+1

@berec - Questo era solo un artefatto casuale di come ho creato quella vecchia immagine istantanea. Ho rigenerato quelle immagini (usando lo stesso codice, sopra). L'alias scelto nel contesto in cui si disegna un tratto non influisce sullo sfondo. Scusa se quella vecchia immagine lo rendeva confuso. – Rob

5

Da dove viene il numero c? Sei sicuro che c si riferisca alla stessa cosa di UIGraphicsGetCurrentContext() nel ciclo di disegno che usi [UIBezierPath stroke]? È difficile da dire dal campione sopra.

Se si vuole essere certi che si sta disegnando allo stesso contesto che si sta configurando, prendere il CGPath dal UIBezierPath e disegnare direttamente:

- (void)drawRect:(CGRect)rect { 
    CGContextRef context = UIGraphicGetCurrentContext(); 
    CGPathRef path = [self.bezier CGPath]; 
    CGContextSetShouldAntialias(context, NO); 
    CGContextAddPath(context, path); 
    CGContextStrokePath(context); 
} 
+0

grazie per il vostro input. hai risolto il mio problema! – alonjr