Как я могу изменить цвет UIImage с помощью программирования, любая помощь, пожалуйста? Если я отправлю UIImage, его цвет должен изменить любую помощь, пожалуйста? Если я изменил цвет RGB с помощью битмафлинга, это не сработает.
Изменение цвета UIImage?
Ответ 1
Если вам нужно только выглядеть иначе, просто используйте 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
Получение и настройка изображения асинхронно уменьшает прокрутку и задержку анимации (особенно при тонировании изображения внутри 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
})
Ответ 2
Один из способов добиться этого - обесцветить изображение и добавить оттенок поверх этого изображения с желаемым цветом.
Desaturate
-(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;
}
How-To
//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];
Вы можете изменить цвет оттенка так, как хотите.
Ответ 3
Отправляй сообщение (в основном просто код для ремикса).
Изменить. Этот код в основном создает новый CGContext
, накладывает на него слой с новым цветом и возвращает из него новый UIImage
. Некоторое время я не углублялся в этот код, но он просто рисует UIImage
с той же формой, что и оригинал, так что предел (теряет любую деталь на изображении).
Ответ 4
Там отличный пост об этом здесь: http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage
Одно из предостережений, которое у меня есть с текущим кодом, заключается в том, что использование его на изображениях сетчатки приведет к потере более высокого разрешения для этих изображений. В настоящее время я ищу решение для этого...
Ответ 5
Если вам нужна высокая производительность, я настоятельно рекомендую вам использовать GPUImage
.
Вы можете загрузить его на https://github.com/BradLarson/GPUImage
Ответ 6
Данные 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);
Ответ 7
Я думаю, вы можете создать другой контекст с настройкой цвета контекста на RGB, который вы хотите покрасить. Затем нарисуйте UIImage в этом контексте и используйте этот контекст вместо того, чтобы напрямую использовать вашу фотографию. Это концепция. Таким образом вы создаете экранный буфер с цветным изображением. Я не пробовал это в cocoa, только в углероде, но я полагаю, что он будет работать одинаково.
Ответ 8
Hmmm - это не порядок байтов, который должен быть RGBA? Вы устанавливаете их как ARGB...
Ответ 9
попробуйте это
- (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;
}
Ответ 10
Отличная статья, упомянутая пользователем576924, отлично поработала для меня: iPhone: как динамически окрашивать UIImage
и быстро:
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" на "kCGBlendModeColor", как указано в разделе комментариев для комментариев.
Ответ 11
Для меня это сработало:
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
}
}