Mi aplicación para iPhone cuenta con UITableViewCell
s personalizados que cada uno tiene un ícono. En el estado de celda normal, estos iconos son negros con un fondo transparente. En lugar de agrupar un segundo conjunto de íconos invertidos con la aplicación para un estado resaltado (blanco sobre un fondo transparente), me gustaría invertir estos íconos sobre la marcha usando Core Graphics siempre que el usuario toque la celda de la tabla correspondiente.Tratando de colorear dinámicamente los UIImages transparentes pero sigue obteniendo un resultado borroso. ¿Qué estoy haciendo mal?
He encontrado algunas otras respuestas relacionadas con superponer UIImage
con un color o volver a colorear UIImage
s, pero todas estas técnicas producen un resultado borroso para mí (ver más abajo). He intentado todo tipo de CGBlendMode
s, así como computar manualmente una máscara más precisa (tal vez lo hice incorrectamente), pero parece que los píxeles semitransparentes alrededor de los bordes de mis iconos obtienen su opacidad borked o son básicamente caerse, dando una apariencia entrecortada/borrosa. Estoy perdido por lo que estoy haciendo mal.
Tampoco es realmente una opción cambiar todos mis íconos de modo que solo sean puros en blanco y negro sin transparencia - Necesito que los iconos queden sobre un fondo transparente para que puedan superponerse sobre otros elementos de la IU como bien.
El código (cortesía de Chadwick Wood) que estoy usando para invertir el ícono (estoy llamando a este método en cada uno de mis iconos originales y pasando [UIColor whiteColor]
como segundo argumento) y el resultado de ejemplo (en un iPhone 4 con iOS 4.1) está debajo (ignore el fondo azul en la imagen resaltada, es el fondo resaltado de una celda de la tabla seleccionada).
Cualquier ayuda es muy apreciada.
Ejemplo de entrada & de salida:
@implementation UIImage(FFExtensions)
+ (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)color {
// load the image
UIImage *img = [UIImage imageNamed:name];
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(img.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
// set the fill color
[color setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, img.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
//CGContextDrawImage(context, rect, img.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rect, img.CGImage);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
@end
¿Cuál es el tamaño de la imagen y cómo la dibuja? ¿Hay una etapa adicional de escalado o está dibujando la imagen en un píxel no integral? –
No es borroso, es de baja resolución. Si compara los tamaños de píxeles de las CGImages de las imágenes, verá que son diferentes. No conozco suficiente Cocoa Touch para decirte cómo solucionarlo, pero ese es el problema que debes resolver. –
@Steven El tamaño de la imagen original que se está coloreando depende del dispositivo. Es 52px (Retina Display) o 26px (iPhone 3G/3GS). El ejemplo que publiqué es la imagen como se ve en un iPhone 4. Parece que de alguna manera la escala está sucediendo, pero no estoy seguro de por qué. De forma deliberada, dejo el argumento .png/@ 2x.png fuera del nombre a esta función para que + imagedNamed: (en la primera línea de la función) elija el archivo de origen correcto según el dispositivo. –