Estoy tratando de dibujar imágenes en el iPhone con esquinas redondeadas, al igual que las imágenes de contacto en la aplicación Contactos. Tengo un código que generalmente funciona, pero ocasionalmente se cuelga dentro de las rutinas de dibujo de UIImage con un EXEC_BAD_ACCESS
- KERN_INVALID_ADDRESS
. Pensé que esto podría estar relacionado con el cropping question que pedí hace unas semanas, pero creo que estoy configurando el trazado de recorte correctamente.Esquinas redondeadas en UIImage
Aquí está el código que estoy usando: cuando no falla, el resultado se ve bien y cualquiera que busque obtener una apariencia similar puede tomar prestado el código.
- (UIImage *)borderedImageWithRect: (CGRect)dstRect radius:(CGFloat)radius {
UIImage *maskedImage = nil;
radius = MIN(radius, .5 * MIN(CGRectGetWidth(dstRect), CGRectGetHeight(dstRect)));
CGRect interiorRect = CGRectInset(dstRect, radius, radius);
UIGraphicsBeginImageContext(dstRect.size);
CGContextRef maskedContextRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(maskedContextRef);
CGMutablePathRef borderPath = CGPathCreateMutable();
CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(180), PNDegreeToRadian(270), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(270.0), PNDegreeToRadian(360.0), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(0.0), PNDegreeToRadian(90.0), NO);
CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(90.0), PNDegreeToRadian(180.0), NO);
CGContextBeginPath(maskedContextRef);
CGContextAddPath(maskedContextRef, borderPath);
CGContextClosePath(maskedContextRef);
CGContextClip(maskedContextRef);
[self drawInRect: dstRect];
maskedImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(maskedContextRef);
UIGraphicsEndImageContext();
return maskedImage;
}
y aquí está el registro de fallos. Se ve igual cada vez que tengo uno de estos accidentes
Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x6e2e6181 Crashed Thread: 0 Thread 0 Crashed: 0 com.apple.CoreGraphics 0x30fe56d8 CGGStateGetRenderingIntent + 4 1 libRIP.A.dylib 0x33c4a7d8 ripc_RenderImage + 104 2 libRIP.A.dylib 0x33c51868 ripc_DrawImage + 3860 3 com.apple.CoreGraphics 0x30fecad4 CGContextDelegateDrawImage + 80 4 com.apple.CoreGraphics 0x30feca40 CGContextDrawImage + 368 5 UIKit 0x30a6a708 -[UIImage drawInRect:blendMode:alpha:] + 1460 6 UIKit 0x30a66904 -[UIImage drawInRect:] + 72 7 MyApp 0x0003f8a8 -[UIImage(PNAdditions) borderedImageWithRect:radius:] (UIImage+PNAdditions.m:187)
¿Por qué haces CGContextSaveGState() y CGContextRestoreGState()? Al leer la documentación, me da la impresión de que el estado es interno al contexto, y que el contexto completo se descarta de todos modos. –
¿Es necesario llamar a CGContextBeginPath() y CGContextClosePath() como lo hace? Descubrí que puedo crear una ruta y llamar a CGContextAddPath() y que las cosas funcionen bien. Además, los documentos para CGContextClosePath() dicen que "cuando llenas o recortas una ruta abierta, Quartz cierra implícitamente el subespacio por ti", lo que sugiere que no hay necesidad de cerrarlo tú mismo. – camdez