如何通过编程更改UIImage的颜色,请帮忙吗?如果我发送UIImage,它的颜色需要改变任何帮助吗?如果我通过bitmaphandling改变RGB颜色,它就不起作用。
答案 0 :(得分:36)
如果你只需要看不同,只需使用imageView.tintColor
(iOS 7+)。 Catch是,设置tintColor
默认情况下不执行任何操作:
要使其有效,请使用imageWithRenderingMode:
var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)
let imageView = ...
imageView.tintColor = UIColor(red: 0.35, green: 0.85, blue: 0.91, alpha: 1)
imageView.image = image
现在它会起作用:
<强>性能强>
配置UIImageView
后设置图像可避免重复昂贵的操作:
// Good usage
let imageView = ...
imageView.tintColor = yourTintColor
var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)
imageView.image = image // Expensive
// Bad usage
var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)
let imageView = ...
imageView.image = image // Expensive
imageView.frame = ... // Expensive
imageView.tintColor = yourTint // Expensive
获得&amp;异步设置图像可以减少滚动和动画延迟(特别是在UICollectionViewCell
或UITableViewCell
内部着色图像时):
let imageView = cell.yourImageView
imageView.image = nil // Clear out old image
imageView.tintColor = UIColor(red: 0.35, green: 0.85, blue: 0.91, alpha: 1)
// Setting the image asynchronously reduces stuttering
// while scrolling. Remember, the image should be set as
// late as possible to avoid repeating expensive operations
// unnecessarily.
dispatch_async(dispatch_get_main_queue(), { () -> Void in
var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)
imageView.image = image
})
答案 1 :(得分:7)
实现此目的的一种方法是对图像进行去饱和处理,并在图像上添加一种色调,并使用您想要的颜色。
<强>去色强>
-(UIImage *) getImageWithUnsaturatedPixelsOfImage:(UIImage *)image {
const int RED = 1, GREEN = 2, BLUE = 3;
CGRect imageRect = CGRectMake(0, 0, image.size.width*2, image.size.height*2);
int width = imageRect.size.width, height = imageRect.size.height;
uint32_t * pixels = (uint32_t *) malloc(width*height*sizeof(uint32_t));
memset(pixels, 0, width * height * sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
uint8_t * rgbaPixel = (uint8_t *) &pixels[y*width+x];
uint32_t gray = (0.3*rgbaPixel[RED]+0.59*rgbaPixel[GREEN]+0.11*rgbaPixel[BLUE]);
rgbaPixel[RED] = gray;
rgbaPixel[GREEN] = gray;
rgbaPixel[BLUE] = gray;
}
}
CGImageRef newImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
UIImage * resultUIImage = [UIImage imageWithCGImage:newImage scale:2 orientation:0];
CGImageRelease(newImage);
return resultUIImage;
}
使用颜色叠加
-(UIImage *) getImageWithTintedColor:(UIImage *)image withTint:(UIColor *)color withIntensity:(float)alpha {
CGSize size = image.size;
UIGraphicsBeginImageContextWithOptions(size, FALSE, 2);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:1.0];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextSetBlendMode(context, kCGBlendModeOverlay);
CGContextSetAlpha(context, alpha);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(CGPointZero.x, CGPointZero.y, image.size.width, image.size.height));
UIImage * tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}
如何对强>
//For a UIImageView
yourImageView.image = [self getImageWithUnsaturatedPixelsOfImage:yourImageView.image];
yourImageView.image = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
//For a UIImage
yourImage = [self getImageWithUnsaturatedPixelsOfImage:yourImage];
yourImage = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
您可以将色调的颜色更改为您想要的颜色。
答案 2 :(得分:2)
查看我的post (mostly just remixing code)。
修改:此代码基本上会创建一个新的CGContext
,使用新颜色在其上绘制一个图层,并从中返回一个新的UIImage
。我有一段时间没有深入研究这段代码,但它似乎只是绘制了一个与原始代码相同的UIImage
,因此这是一个限制(丢失图像中的任何细节)。
答案 3 :(得分:2)
这里有一篇很棒的帖子: http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage
我对当前代码的一个警告是,在视网膜图像上使用它会导致这些图像的“分辨率”降低。我目前正在为此寻找解决方案......
答案 4 :(得分:2)
如果您需要高性能,我强烈建议您使用GPUImage
。
您可以在https://github.com/BradLarson/GPUImage
答案 5 :(得分:1)
您正在操作的RGB数据只是一个副本。完成更改后,您需要将该数据转换回图像。
我首先制作一个新的位图:
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
ctx = CGBitmapContextCreate( malloc(dataSize), width, height,
8, // CGImageGetBitsPerComponent(cgImage),
bytesPerRow, //CGImageGetBytesPerRow(cgImage),
space,
//kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big );
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little);
//kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
CGColorSpaceRelease( space );
// now draw the image into the context
CGRect rect = CGRectMake( 0, 0, CGImageGetWidth(cgImage), CGImageGetHeight(cgImage) );
CGContextDrawImage( ctx, rect, cgImage );
获取像素:
pixels = CGBitmapContextGetData( ctx );
假设您的像素数据来自pixels = CGBitmapContextGetData( ctx );
,则获取该上下文并从中构建新图像:
CGImageRef newImg = CGBitmapContextCreateImage(ctx);
[[UIImage imageWithCGImage:newImg] drawInRect:rect];
CGImageRelease(newImg);
答案 6 :(得分:0)
我认为您可以创建另一个上下文,将上下文颜色设置为RGB,以便为图片着色。然后将您的UIImage绘制到该上下文中并使用该上下文而不是直接使用您的图片。这是一个概念。这样您就可以使用彩色图像创建屏幕外缓冲区。我没有在可可中尝试这种方法,只是在碳中,但我想它会以同样的方式起作用。
答案 7 :(得分:0)
嗯 - 不是应该是RGBA的字节的顺序?您将它们设置为ARGB ...
答案 8 :(得分:0)
试试这个
- (UIImage *)imageWithOverlayColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);
if (UIGraphicsBeginImageContextWithOptions) {
CGFloat imageScale = 1.0f;
if ([self respondsToSelector:@selector(scale)]) // The scale property is new with iOS4.
imageScale = self.scale;
UIGraphicsBeginImageContextWithOptions(self.size, NO, imageScale);
}
else {
UIGraphicsBeginImageContext(self.size);
}
[self drawInRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
答案 9 :(得分:0)
user576924提到的好帖子对我很有帮助: iPhone: How to Dynamically Color a UIImage
并在swift中:
extension UIImage {
func imageWithColor( color : UIColor ) -> UIImage {
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(self.size)
// get a reference to that context we created
let context = UIGraphicsGetCurrentContext();
// set the fill color
color.setFill()
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, self.size.height)
CGContextScaleCTM(context, 1.0, -1.0)
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColor)
let rect = CGRect(origin: CGPointZero, size: self.size)
CGContextDrawImage(context, rect, self.CGImage)
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rect, self.CGImage)
CGContextAddRect(context, rect)
CGContextDrawPath(context,kCGPathFill)
// generate a new UIImage from the graphics context we drew onto
let coloredImg = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//return the color-burned image
return coloredImg
}
}
请注意,我也更改了&#34; kCGBlendModeColorBurn&#34; to&#34; kCGBlendModeColor&#34;正如帖子评论部分所述。
答案 10 :(得分:0)
对我来说这很有效:
extension UIImage {
class func image(image: UIImage, withColor color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(image.size.width, image.size.height), false, image.scale)
let context = UIGraphicsGetCurrentContext()
color.set()
CGContextTranslateCTM(context, 0, image.size.height)
CGContextScaleCTM(context, 1, -1)
let rect = CGRectMake(0, 0, image.size.width, image.size.height)
CGContextClipToMask(context, rect, image.CGImage)
CGContextFillRect(context, rect)
let coloredImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return coloredImage
}
}