尝试动态为透明 UIImage 着色,但结果始终模糊。我做错了什么?
我的 iPhone 应用程序具有自定义 UITableViewCell
,每个都有一个图标。在正常的单元格状态下,这些图标是黑色的,背景透明。我不想将第二组反转图标与应用程序捆绑在一起以实现突出显示状态(透明背景上的白色),而是希望在用户触摸相应的表格单元格时使用 Core Graphics 即时反转这些图标。
我找到了一些与用颜色覆盖 UIImage
或重新着色 UIImage
相关的其他答案,但所有这些技术都会为我产生模糊的结果(请参阅以下)。我尝试过各种 CGBlendMode ,以及手动计算更准确的蒙版(也许我做得不正确),但图标边缘周围的半透明像素似乎是它们的不透明度被破坏或基本上被丢弃 - 呈现出不稳定/模糊的外观。我对自己做错的事情感到不知所措。
它也不是真正改变我的所有图标的选项,使它们只是纯黑/白,没有透明度 - 我需要图标位于透明背景上,以便它们也可以覆盖在其他 UI 元素之上。
我用来反转图标的代码(由 Chadwick Wood 提供)(我在每个原始图标上调用此方法并传入 [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
My iPhone app features custom UITableViewCell
s that each feature an icon. In the normal cell state, these icons are black with a transparent background. Instead of bundling a second set of inverted icons with the app for a highlighted state (white on a transparent background) I'd like to invert these icons on-the-fly using Core Graphics whenever the user touches the corresponding table cell.
I've found some other answers related to overlaying a UIImage
with a color, or re-coloring UIImage
s, but all of these techniques produce a blurry result for me (see below). I've tried all kinds of CGBlendMode
s, as well as manually computing a more accurate mask (perhaps I did it incorrectly), but it seems that the semi-transparent pixels around the edges of my icons are getting their opacity borked or are basically being dropped - giving a choppy/blurred appearance. I'm at a loss for what I'm doing wrong.
It's also not really an option to change all my icons so that are just pure black/white with no transparency - I need the icons to sit on a transparent background so that they can be overlaid on top of other UI elements as well.
The code (courtesy of Chadwick Wood) that I'm using to invert the icon (I'm calling this method on each of my original icons and passing in [UIColor whiteColor]
as the second argument) and example output (on an iPhone 4 with iOS 4.1) is below (ignore the blue background on the highlighted image - it is the highlighted background of a selected table cell).
Any help is greatly appreciated.
Example input & output:
@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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
感谢彼得和史蒂文观察到输出图像的分辨率似乎低于输入图像,我意识到在创建图像上下文时我没有考虑屏幕的比例因子。
更改线路:
解决
问题。
Thanks to Peter & Steven's observation that the resolution of the output image seemed to be lower than the input, I realized that I was not accounting for the scale factor of the screen when creating my image context.
Changing the line:
to
fixes the problem.