Iphone 图像颜色改变?
如何通过编程更改UIImage的颜色,请提供帮助?如果我发送一个UIImage,它的颜色需要更改,请提供帮助?如果我通过位图处理更改RGB颜色,它将不起作用。我认为您可以创建另一个上下文,将上下文颜色设置为要为图片上色的RGB。然后将UIImage绘制到该上下文中,并使用该上下文,而不是直接使用图片。这是一个概念。这样,您就可以用彩色图像创建屏幕外缓冲区。我没有在可可粉中尝试,只是在碳纤维中,但我想它也会以同样的方式工作。您正在操作的RGB数据只是一个副本。完成更改后,需要将该数据转换回图像 我首先创建一个新位图:Iphone 图像颜色改变?,iphone,Iphone,如何通过编程更改UIImage的颜色,请提供帮助?如果我发送一个UIImage,它的颜色需要更改,请提供帮助?如果我通过位图处理更改RGB颜色,它将不起作用。我认为您可以创建另一个上下文,将上下文颜色设置为要为图片上色的RGB。然后将UIImage绘制到该上下文中,并使用该上下文,而不是直接使用图片。这是一个概念。这样,您就可以用彩色图像创建屏幕外缓冲区。我没有在可可粉中尝试,只是在碳纤维中,但我想它也会以同样的方式工作。您正在操作的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);
嗯,字节的顺序不是应该是RGBA吗?您正在将它们设置为ARGB…请查看我的
编辑:此代码基本上创建一个新的CGContext
,用新颜色在其上绘制一层,并从中返回一个新的UIImage
。我已经有一段时间没有深入研究这段代码了,但它似乎只是画了一幅与原作形状相同的UIImage
,所以这是一个限制(在图像中丢失任何细节)。这里有一篇关于这一点的文章:
我对当前代码的一个警告是,在视网膜图像上使用它将导致这些图像失去更高的“分辨率”。我目前正在寻找一种解决方案…实现这一点的一种方法是降低图像的饱和度,并在图像顶部添加一种您想要的颜色
去饱和
-(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;
}
如何
//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];
您可以根据自己的需要更改色调。试试这个
- (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;
}
如果您只需要它看起来不同,只需使用imageView.tintColor
(iOS 7+)。问题是,默认情况下,设置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
现在它将起作用:
性能
-(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;
}
配置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
异步获取和设置图像可减少滚动和动画延迟(尤其是在UICollectionViewCell
或UITableViewCell
中着色图像时):
如果您需要高性能,我强烈建议您使用GPUImage
。
您可以从下载,用户576924提到的伟大帖子对我来说非常有用:
以迅捷的速度:
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
}
}
请注意,我还将“kCGBlendModeColorBurn”更改为“kCGBlendModeColorBurn”,如帖子评论部分所述。对我来说,这很有效:
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
}
}
这个类不只是一个图像而不是一种颜色吗?你到底在问什么?我想以编程的方式更改UIimage的颜色…当我这样调用[self-changeImagecolor:myImage color:[UIColor redcolor]]时,函数假设;函数必须返回我提到的带有颜色的图像。。。。。我知道我必须使用位图数据。。。你能帮忙吗?你可以查看这个链接。它工作得很好。你能接受答案吗?我使用UIGraphicsBeginImageContext从图像中获取上下文。但它不起作用?请看这个帖子:所以首先将该上下文中的当前颜色设置为要为图片上色的RGB,然后绘制图片。完成后,使用您创建的上下文,而不是原始图片。它是否适合您?我试过了,它没有给出结果吗?你做错了什么,我不能告诉你它是什么而不知道你在更改位图后做了什么。你如何把它变回图像?在StackOverflow上搜索“[iphone]位图图像”。这里有大量的问题和答案。为了确保您正确获取像素数据,请阅读此内容。我完全按照苹果的要求做了,请再次查看我的问题。。。。。?返回的图像不是黑色的…bcos我使用了r-0、g-0、b-0。请忽略透明部分。嘿,这很好,但我注意到,在具有透明度的PNG文件上使用这两种方法时,即使透明像素也会着色。任何解决方案?要使用源alpha将源颜色覆盖为您的颜色,请使用此混合模式(R=S*Da):CGContextSetBlendMode(上下文,kCGBlendModeSourceIn);在方法GetImageWithTintedColor中,原始代码不适用于灰色,但注释是正确的。实际上附加的图像是不正确的。它的背景是白色的,但应该是透明的。@Voloda2你说得对,你需要一个透明的图像。它在目标cI中如何运行?我在UIBarButtonItem中使用的UIButton
有这个问题。应该设置哪个图像?我用setImage(for:.normal)
配置了我在按钮中设置的图像,但没有什么区别。我发现这个链接最适合我。我所做的唯一改变是在那篇文章的评论中推荐的:使用kCGBlendModeColor而不是kCGBlendModeColorBurn使混合模式工作得更好。我还用swift重写了它-请参阅我的其他关于该线程的答案。我得到一个错误,即“kCGPathFill”是一个未解析的标识符。我需要进口什么?谢谢
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
}
}