尝试动态着色透明的UIImages,但不断获得模糊的结果.我究竟做错了什么?

Jon*_* G. 5 iphone core-graphics image-processing quartz-graphics

我的iPhone应用程序具有自定义UITableViewCell功能,每个功能都带有图标 在正常的单元状态下,这些图标是黑色的,具有透明背景.而不是将应用程序的第二组倒置图标与突出显示的状态(透明背景上的白色)捆绑在一起,我想在用户触摸相应的表格单元格时使用Core Graphics即时反转这些图标.

我发现了一些UIImage与用颜色重叠或重新着色相关的其他答案UIImage,但所有这些技巧都会给我带来模糊的结果(见下文).我已经尝试了各种各样的CGBlendModes,以及手动计算更准确的面具(也许我做错了),但似乎我的图标边缘周围的半透明像素变得不透明或者基本上是掉落 - 外观波动/模糊.因为我做错了,我感到很茫然.

它也不是真正改变我所有图标的选项,因此它只是纯黑色/白色而没有透明度 - 我需要将图标放在透明背景上,以便它们也可以叠加在其他UI元素之上.

我用来反转图标的代码(由查德威克伍德提供)(我在每个原始图标上调用此方法并[UIColor whiteColor]作为第二个参数传入)和示例输出(在带有iOS 4.1的iPhone 4上)在下方(忽略突出显示图像上的蓝色背景 - 它是所选表格单元格的突出显示背景).

任何帮助是极大的赞赏.

示例输入和输出:

程序化重新着色之前和之后的图标.

@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
Run Code Online (Sandbox Code Playgroud)

Jon*_* G. 5

感谢Peter&Steven观察到输出图像的分辨率似乎低于输入,我意识到在创建图像上下文时我没有考虑屏幕的比例因子.

换行:

UIGraphicsBeginImageContext(img.size);
Run Code Online (Sandbox Code Playgroud)

UIGraphicsBeginImageContextWithOptions(img.size, NO, [UIScreen mainScreen].scale);
Run Code Online (Sandbox Code Playgroud)

解决了这个问题.

  • 或者,更简单:只需将0.0作为最后一个参数传递给`UIGraphicsBeginImageContextWithOptions()`.从[文档](http://developer.apple.com/library/ios/documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html#//apple_ref/c/func/UIGraphicsBeginImageContextWithOptions):"如果指定一个值为0.0时,比例因子设置为设备主屏幕的比例因子." (2认同)