iPhone - Как вы окрашиваете изображение? - PullRequest
34 голосов
/ 03 августа 2009

Мне бы очень хотелось узнать, как раскрасить изображение (например, сделать белый .png красным). Я видел различные предложения, но никогда не подтверждал, что это действительно возможно. Я пробовал это:

-(UIImage *)colorizeImage:(UIImage *)baseImage color:(UIColor *)theColor {
    UIGraphicsBeginImageContext(baseImage.size);

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGRect area = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height);

    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -area.size.height);
    CGContextSaveGState(ctx);
    CGContextClipToMask(ctx, area, baseImage.CGImage);
    [theColor set];
    CGContextFillRect(ctx, area);
    CGContextRestoreGState(ctx);
    CGContextSetBlendMode(ctx, kCGBlendModeNormal);
    CGContextDrawImage(ctx, area, baseImage.CGImage);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

myImageView.image = [self colorizeImage:[UIImage imageNamed:@"whiteImage.png"] color:[UIColor redColor]];

Но это не работает - изображение все еще белое на экране.

Ответы [ 9 ]

64 голосов
/ 07 января 2011

Сделать эту категорию UIImage. Также учитывается масштабный коэффициент с iOS 4.

- (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;
}

ОБНОВЛЕНИЕ - Swift версия:

func imageWithColor(color: UIColor) -> UIImage {
    let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
    UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0);
    drawInRect(rect)
    let context = UIGraphicsGetCurrentContext()
    CGContextSetBlendMode(context, .SourceIn)
    CGContextSetFillColorWithColor(context, color.CGColor)
    CGContextFillRect(context, rect);
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}
12 голосов
/ 16 декабря 2009

Измените режим смешивания на , умножьте , и ваш код будет работать:

CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
10 голосов
/ 08 декабря 2014

Начиная с iOS 7, вы можете тонировать изображения одним цветом, например

Цель C

UIImage *image = [UIImage imageNamed:@"myImage.png"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
imageView.tintColor = [UIColor redColor];

Swift 3

let image = UIImage(named:"myImage.png")?.withRenderingMode(.alwaysTemplate)
let imageView = UIImageView(image:image)
imageView.tintColor = .red

Это закрасит все изображение одним цветом и сохранит альфа-канал.

2 голосов
/ 19 мая 2015

Я думаю, что лучший способ раскрасить изображение из iOS7 - указать свойство UIImageRenderingModeAlwaysTemplate на изображении:

myImageView.image = [[UIImage imageNamed:@"myImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

, а затем раскрасьте его цветом tintColor изображения.

myImageView.tintColor = [UIColor purpleColor]; //Maybe purple is not the best choice ;)

Я думаю, что это проще (категория не нужна) и, конечно, оптимизировано!

Примечание: если вы используете xcassets, вы можете установить для свойства рендеринга значение UIImageRenderingModeAlwaysTemplate в XCode, как на этом скриншоте:

UIImageRenderingModeAlwaysTemplate in XCode

1 голос
/ 21 апреля 2016

Коротко, сладко и лучше :) 1001 *

- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color

Определите UIColorFromRGB для использования шестнадцатеричных цветовых кодов, затем просто наберите colorizeImage:withColor

#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIImage *imgToColor = [UIImage imageNamed:@"myImage.png"];
    imgToColor = [self colorizeImage:imgToColor withColor:UIColorFromRGB(0xff00ff)];
    // use normal UIColor or UIColorFromRGB() for hex
}

 - (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
    UIGraphicsBeginImageContextWithOptions(image.size, NO, [[UIScreen mainScreen] scale]);
    [image drawInRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(context, kCGBlendModeSourceIn);

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
1 голос
/ 14 октября 2010

@ чудак, дай мне знать, поможет ли это тебе, чувак ...

// 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);

// заменить "context" на UIGraphicsGetCurrentContext() или, если у вас есть экземпляр текущего контекста.

Надеюсь, это поможет.

1 голос
/ 03 августа 2009

Хорошо, как это?

На этапе создания ресурсов (НЕ динамически во время работы приложения) инвертируйте цветовую схему изображений. Часть, которая теперь белая -> прозрачная. Часть, которая теперь прозрачна -> независимо от фона страницы.

Под каждым изображением поместите пустой белый вид того же размера. Если вы хотите превратить изображение в красное, измените цвет этого пустого белого вида на красный.

Это выполнимо?

0 голосов
/ 03 августа 2009

Сначала вы рисуете цвет, а затем рисуете изображение поверх него. Если изображение не является частично прозрачным, оно полностью заменит цвет фона. Я рекомендую сначала нарисовать исходное изображение, а затем нарисовать красным поверх него, используя kCGBlendModeHue.

Я не уверен, почему вы переключаете и переводите свой контекст. Ваша картинка перевернута?

0 голосов
/ 03 августа 2009

Если установить для backgroundColor UIImageView значение [UIColor redColor], части исходного PNG, которые были прозрачными , станут красными. В качестве альтернативы, вы можете попробовать добавить полупрозрачный UIView с красным цветом фона в качестве подпредставления изображения. Это добавит красную дымку к виду, отображающему изображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...