ios:更改 UIImage 的颜色
Posted
技术标签:
【中文标题】ios:更改 UIImage 的颜色【英文标题】:ios: change the colors of a UIImage 【发布时间】:2012-09-05 22:46:51 【问题描述】:我正在开发一个 Iphone 应用程序。
我有代表符号的 png 图片。符号全黑,背景透明。
有没有办法可以将黑色变成另一种颜色?我正在寻找的是可以帮助我选择我想要的颜色的东西,并且在使用符号时(在 UIImage 中)我可以让它们显示为我选择的颜色。
我四处搜索,发现了一个名为 OpenCV 的框架,它可以处理图像,但我不知道如何为图片重新着色。
非常感谢任何帮助和建议。
谢谢
【问题讨论】:
你为什么不在photoshop中编辑它?这对你来说更容易 我有 1500 个符号,每周都在变化。我不确定这是个好主意 【参考方案1】:要使用objective-c 处理图像,主要你必须使用Quartz 2D/CoreGraphics 框架。我想这将是您完成任务的最简单方法。
Quartz 2D 指南的链接是here ,该指南非常全面。只需看看用颜色填充位图的某个地方。
我的博客里也有一些关于重度图像处理的记录,你可以看看,它可能会有所帮助。 http://levonp.blogspot.de/2012/05/quartz-getting-diff-images-of-two.html
当然,你也可以使用更高级的东西,如 OpenGL、OpenCV 等。
【讨论】:
【参考方案2】:您可以创建存储 UIImageView 并更改 UIview 背景颜色的 UIView。
UIView *viewForImage = ....;
UIImageView *imageView = .....;
...
[viewForImage addSubview: imageView];
[self.view addSubview:viewForImage];
...
然后使用例如
[viewForImage setBackgroundColor: [UIColor redColor]];
【讨论】:
【参考方案3】:你可以使用这个类别文件来改变图像的整个颜色......
.h 文件:
#import <UIKit/UIKit.h>
@interface UIImage (AddtionalFunctionalities)
//TintColor...
- (UIImage *)imageWithTint:(UIColor *)tintColor;
//scale and resize...
-(UIImage*)scaleToSize:(CGSize)size;
@end
.m 文件:
#import "UIImage+AddtionalFunctionalities.h"
@implementation UIImage (AddtionalFunctionalities)
- (UIImage *)imageWithTint:(UIColor *)tintColor
// Begin drawing
CGRect aRect = CGRectMake(0.f, 0.f, self.size.width, self.size.height);
CGImageRef alphaMask;
//
// Compute mask flipping image
//
UIGraphicsBeginImageContext(aRect.size);
CGContextRef c = UIGraphicsGetCurrentContext();
// draw image
CGContextTranslateCTM(c, 0, aRect.size.height);
CGContextScaleCTM(c, 1.0, -1.0);
[self drawInRect: aRect];
alphaMask = CGBitmapContextCreateImage(c);
UIGraphicsEndImageContext();
//
UIGraphicsBeginImageContext(aRect.size);
// Get the graphic context
CGContextRef c = UIGraphicsGetCurrentContext();
// Draw the image
[self drawInRect:aRect];
// Mask
CGContextClipToMask(c, aRect, alphaMask);
// Set the fill color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextSetFillColorSpace(c, colorSpace);
// Set the fill color
CGContextSetFillColorWithColor(c, tintColor.CGColor);
UIRectFillUsingBlendMode(aRect, kCGBlendModeNormal);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Release memory
CGColorSpaceRelease(colorSpace);
CGImageRelease(alphaMask);
return img;
-(UIImage*)scaleToSize:(CGSize)size
// Create a bitmap graphics context
// This will also set it as the current context
UIGraphicsBeginImageContext(size);
// Draw the scaled image in the current context
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
// Create a new image from current context
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// Pop the current context from the stack
UIGraphicsEndImageContext();
// Return our new scaled image
return scaledImage;
@end
方法调用将是:
self.outputImage.image=[sourceImage imageWithTint:[UIColor redColor]];
如果你想使用图片,请使用这个:
self.outputImage.image=[sourceImage imageWithTint:[UIColor colorWithPatternImage:[UIImage imageNamed: @"red.jpg"]]];
希望对你有帮助...
【讨论】:
注意:这会将整个图像更改为一种颜色...(例如黑色,蓝色) kCGBlendModeNormal 应该是 kCGBlendModeColor 谢谢你.. 就像一个魅力.. :) 我希望我能投票两次。【参考方案4】:你想改变删除/一种特定的颜色意味着使用下面的类别....
.h 文件:
#import <UIKit/UIKit.h>
@interface UIImage (Color)
+ (UIImage*)setBackgroundImageByColor:(UIColor *)backgroundColor withFrame:(CGRect )rect;
+ (UIImage*) replaceColor:(UIColor*)color inImage:(UIImage*)image withTolerance:(float)tolerance;
+(UIImage *)changeWhiteColorTransparent: (UIImage *)image;
+(UIImage *)changeColorTo:(NSMutableArray*) array Transparent: (UIImage *)image;
//resizing Stuff...
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize;
@end
.m 文件
#import <QuartzCore/QuartzCore.h>
#import "UIImage+Color.h"
@implementation UIImage (Color)
+ (UIImage* )setBackgroundImageByColor:(UIColor *)backgroundColor withFrame:(CGRect )rect
// tcv - temporary colored view
UIView *tcv = [[UIView alloc] initWithFrame:rect];
[tcv setBackgroundColor:backgroundColor];
// set up a graphics context of button's size
CGSize gcSize = tcv.frame.size;
UIGraphicsBeginImageContext(gcSize);
// add tcv's layer to context
[tcv.layer renderInContext:UIGraphicsGetCurrentContext()];
// create background image now
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
// [tcv release];
+ (UIImage*) replaceColor:(UIColor*)color inImage:(UIImage*)image withTolerance:(float)tolerance
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
NSUInteger bitmapByteCount = bytesPerRow * height;
unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char));
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGColorRef cgColor = [color CGColor];
const CGFloat *components = CGColorGetComponents(cgColor);
float r = components[0];
float g = components[1];
float b = components[2];
//float a = components[3]; // not needed
r = r * 255.0;
g = g * 255.0;
b = b * 255.0;
const float redRange[2] =
MAX(r - (tolerance / 2.0), 0.0),
MIN(r + (tolerance / 2.0), 255.0)
;
const float greenRange[2] =
MAX(g - (tolerance / 2.0), 0.0),
MIN(g + (tolerance / 2.0), 255.0)
;
const float blueRange[2] =
MAX(b - (tolerance / 2.0), 0.0),
MIN(b + (tolerance / 2.0), 255.0)
;
int byteIndex = 0;
while (byteIndex < bitmapByteCount)
unsigned char red = rawData[byteIndex];
unsigned char green = rawData[byteIndex + 1];
unsigned char blue = rawData[byteIndex + 2];
if (((red >= redRange[0]) && (red <= redRange[1])) &&
((green >= greenRange[0]) && (green <= greenRange[1])) &&
((blue >= blueRange[0]) && (blue <= blueRange[1])))
// make the pixel transparent
//
rawData[byteIndex] = 0;
rawData[byteIndex + 1] = 0;
rawData[byteIndex + 2] = 0;
rawData[byteIndex + 3] = 0;
byteIndex += 4;
UIImage *result = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGContextRelease(context);
free(rawData);
return result;
+(UIImage *)changeWhiteColorTransparent: (UIImage *)image
CGImageRef rawImageRef=image.CGImage;
const float colorMasking[6] = 222, 255, 222, 255, 222, 255;
UIGraphicsBeginImageContext(image.size);
CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking);
//if in iphone
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height);
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
CGImageRelease(maskedImageRef);
UIGraphicsEndImageContext();
return result;
+(UIImage *)changeColorTo:(NSMutableArray*) array Transparent: (UIImage *)image
CGImageRef rawImageRef=image.CGImage;
// const float colorMasking[6] = 222, 255, 222, 255, 222, 255;
const float colorMasking[6] = [[array objectAtIndex:0] floatValue], [[array objectAtIndex:1] floatValue], [[array objectAtIndex:2] floatValue], [[array objectAtIndex:3] floatValue], [[array objectAtIndex:4] floatValue], [[array objectAtIndex:5] floatValue];
UIGraphicsBeginImageContext(image.size);
CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking);
//if in iphone
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height);
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
CGImageRelease(maskedImageRef);
UIGraphicsEndImageContext();
return result;
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
//UIGraphicsBeginImageContext(newSize);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
@end
我通过此代码将移除的白色更改为透明......
电话将是...
self.rawImage.image=[UIImage changeWhiteColorTransparent:originalStateImage];
我希望这个想法对你有所帮助....
【讨论】:
您能否举例说明changeColorTo
方法的用法。即数组参数应该包含什么?
我需要在运行时用不同颜色替换所有白色像素,保持 alpha 值相同。例如RGBA 为 255,255,255,255 -> 128,128,128,255。但是 RGBA 为 255,255,255,128 -> 128,128,128,128。你的changeColorTo
方法是我想要的吗?
如果您希望图像在 Retina 设备上看起来清晰,您应该使用 UIGraphicsBeginImageContextWithOptions()
。
感谢作者。这是该代码可能来自的存储库:github.com/AckeeCZ/ACKategories/blob/master/UIImage%2BColor.h
链接搞砸了。 github.com/AckeeCZ/ACKategories/tree/master/ACKategories/UIKit有问题的类别在UIImage+Color.h【参考方案5】:
最简单最短的:
当您与UIImageView
打交道时,该怎么做:
Obj-C:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
斯威夫特:
let theImageView = UIImageView(image: UIImage(named:"foo")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate))
theImageView.tintColor = UIColor.redColor()
【讨论】:
我同意这一点。漂亮。 我第三!简直美极了。不仅在它的简单性上,而且在它的效果上:一个很好的平滑着色效果,没有像素化。非常感谢 Skywinder! 简洁优雅。很好的答案。 该问题要求您对 UIImage 对象而不是 UIImageView 执行背景颜色更改。在某些情况下,您希望能够做到这一点,而不是在视图容器上设置色调。 这就是为什么我们也应该阅读不被接受的答案。绿色刻度很烂@***【参考方案6】:设置图像渲染模式,然后为颜色目的使用 tintcolor 属性。
yourImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [yourImageView setTintColor:[UIColor redColor]];
【讨论】:
【参考方案7】:更改图像颜色的非常简单的解决方案。想法:UIImage 和 UIImageView 的扩展。
Swift 3,Xcode 8.1。 https://***.com/a/40884483/4488252
我的回答中的代码示例(上面的链接):
// use extension UIImage
newImageView = createNewImageView(x: 100)
newImageView.image = UIImage(named: "Apple")?.imageWithColor(newColor: UIColor.blue)
// use extension UIImageView
newImageView = createNewImageView(x: 160)
newImageView.image = UIImage(named: "Apple")
newImageView.imageColor = UIColor.green
【讨论】:
【参考方案8】:适用于 ios 13.0
Obj-C:
self.yourImageView.image = [self.yourImageView.image imageWithTintColor:[UIColor.redColor]];
斯威夫特:
yourImageView.image = yourImageView.image.withTintColor(UIColor.red);
如果图片来自 Asset Catalog,您可以在 Attribute Inspector
中更改渲染
【讨论】:
以上是关于ios:更改 UIImage 的颜色的主要内容,如果未能解决你的问题,请参考以下文章
使用遮罩更改 UIImage 的颜色并将该图像替换为彩色图像
点击 tableview 单元格时如何更改 UIImage 颜色?
我可以更改 UIButton 上的色调颜色,但不能更改 UIImage
Swift 3 ios:当图像出现时,UILabel 需要出现在 UIImage 之上