如何在iOS上以程序方式着色图像?
image-processing
ios
5
0

我想为图像添加色彩参考。结果应该看起来像Photoshop中的“乘法”混合模式,其中白色将替换为“ 色调”

替代文字

我将不断更改颜色值。

后续:我会将代码执行此操作,并将其放入ImageView的drawRect:方法中,对吗?

像往常一样,与链接相反, 代码片段将极大地帮助我理解。

更新:用建议的代码Ramin子类化UIImageView。

我把它放在我的视图控制器的viewDidLoad:中:

[self.lena setImage:[UIImage imageNamed:kImageName]];
[self.lena setOverlayColor:[UIColor blueColor]];
[super viewDidLoad];

我看到了图像,但是没有着色。我还尝试加载其他图像,在IB中设置图像,然后在视图控制器中调用setNeedsDisplay:。

更新 :未调用drawRect :。

最终更新:我发现一个旧项目已正确设置了imageView,因此我可以测试Ramin的代码,并且它的工作原理很吸引人!

最终,最终更新:

对于那些刚刚了解Core Graphics的人来说,这是可能可行的最简单的方法。

在子类化的UIView中:

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColor(context, CGColorGetComponents([UIColor colorWithRed:0.5 green:0.5 blue:0 alpha:1].CGColor)); // don't make color too saturated

    CGContextFillRect(context, rect); // draw base

    [[UIImage imageNamed:@"someImage.png"] drawInRect: rect blendMode:kCGBlendModeOverlay alpha:1.0]; // draw image
}
参考资料:
Stack Overflow
收藏
评论
共 8 个回答
高赞 时间 活跃

这是实现图像着色的另一种方法,特别是如果您已经使用QuartzCore进行其他操作的话。这是我对类似问题的回答

导入QuartzCore:

#import <QuartzCore/QuartzCore.h>

创建透明的CALayer并将其添加为要着色的图像的子层:

CALayer *sublayer = [CALayer layer];
[sublayer setBackgroundColor:[UIColor whiteColor].CGColor];
[sublayer setOpacity:0.3];
[sublayer setFrame:toBeTintedImage.frame];
[toBeTintedImage.layer addSublayer:sublayer];

将QuartzCore添加到您的项目Framework列表中(如果尚未存在),否则会出现如下编译错误:

Undefined symbols for architecture i386: "_OBJC_CLASS_$_CALayer"
收藏
评论

对于那些试图将UIImageView类子类化并陷入“ drawRect:未被调用”的人,请注意,您应该对UIView类进行子类化,因为对于UIImageView类,不会调用“ drawRect:”方法。在此处阅读更多内容: 在我的UIImageView的子类中未调用drawRect

收藏
评论

在iOS7中,他们在UIImageView上引入了tintColor属性,在UIImage上引入了renderingMode。要在iOS7上着色UIImage,您要做的就是:

UIImageView* imageView = …
UIImage* originalImage = …
UIImage* imageForRendering = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
imageView.image = imageForRendering;
imageView.tintColor = [UIColor redColor]; // or any color you want to tint it with
收藏
评论

首先,您需要继承UIImageView并重写drawRect方法。您的类需要一个UIColor属性(我们将其称为overlayColor)来保存混合颜色,以及一个自定义设置器,当颜色更改时,该设置器将强制重绘。像这样:

- (void) setOverlayColor:(UIColor *)newColor {
   if (overlayColor)
     [overlayColor release];

   overlayColor = [newColor retain];
   [self setNeedsDisplay]; // fires off drawRect each time color changes
}

在drawRect方法中,您将要先绘制图像,然后在其上覆盖一个填充有所需颜色的矩形以及适当的混合模式,如下所示:

- (void) drawRect:(CGRect)area
{
  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSaveGState(context);

  // Draw picture first
  //
  CGContextDrawImage(context, self.frame, self.image.CGImage);

  // Blend mode could be any of CGBlendMode values. Now draw filled rectangle
  // over top of image.
  //
  CGContextSetBlendMode (context, kCGBlendModeMultiply);
  CGContextSetFillColor(context, CGColorGetComponents(self.overlayColor.CGColor));      
  CGContextFillRect (context, self.bounds);
  CGContextRestoreGState(context);
}

通常,为了优化图形,您将实际图形限制为仅传递给drawRect的区域,但是由于每次颜色更改时都必须重新绘制背景图像,因此很可能需要刷新整个事物。

要使用它,请创建对象的实例,然后将image属性(从UIImageView继承)设置为picture,并将overlayColor设置为UIColor值(可以通过更改向下传递的颜色的alpha值来调整混合级别)。

收藏
评论
UIImage * image = mySourceImage;
UIColor * color = [UIColor yellowColor];  
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height) blendMode:kCGBlendModeNormal alpha:1];
UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, image.size.width, image.size.height)];
[color setFill];
[path fillWithBlendMode:kCGBlendModeMultiply alpha:1]; //look up blending modes for your needs
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//use newImage for something
收藏
评论

我想用alpha着色图像,并创建了以下课程。如果您发现任何问题,请告诉我。

我已经将类命名为CSTintedImageView并且它继承自UIView因为UIImageView不调用drawRect:方法,如先前的答复中所述。我已经设置了一个指定的初始化程序,该初始化程序类似于在UIImageView类中找到的初始化程序。

用法:

CSTintedImageView * imageView = [[CSTintedImageView alloc] initWithImage:[UIImage imageNamed:@"image"]];
imageView.tintColor = [UIColor redColor];

CSTintedImageView.h

@interface CSTintedImageView : UIView

@property (strong, nonatomic) UIImage * image;
@property (strong, nonatomic) UIColor * tintColor;

- (id)initWithImage:(UIImage *)image;

@end

CSTintedImageView.m

#import "CSTintedImageView.h"

@implementation CSTintedImageView

@synthesize image=_image;
@synthesize tintColor=_tintColor;

- (id)initWithImage:(UIImage *)image
{
    self = [super initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];

    if(self)
    {
        self.image = image;

        //set the view to opaque
        self.opaque = NO;
    }

    return self;
}

- (void)setTintColor:(UIColor *)color
{
    _tintColor = color;

    //update every time the tint color is set
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();    

    //resolve CG/iOS coordinate mismatch
    CGContextScaleCTM(context, 1, -1);
    CGContextTranslateCTM(context, 0, -rect.size.height);

    //set the clipping area to the image
    CGContextClipToMask(context, rect, _image.CGImage);

    //set the fill color
    CGContextSetFillColor(context, CGColorGetComponents(_tintColor.CGColor));
    CGContextFillRect(context, rect);    

    //blend mode overlay
    CGContextSetBlendMode(context, kCGBlendModeOverlay);

    //draw the image
    CGContextDrawImage(context, rect, _image.CGImage);    
}

@end
收藏
评论

请快速澄清一下(经过对该主题的一些研究之后)。苹果文档在此明确指出:

UIImageView类经过优化,可以将其图像绘制到显示器上。 UIImageView不会调用其子类的drawRect:方法。如果您的子类需要包含自定义绘图代码,则应改为UIView类的子类。

因此,甚至不要浪费任何时间尝试在UIImageView子类中重写该方法。从UIView开始。

收藏
评论

这可能非常有用:PhotoshopFramework是一个功能强大的库,可以在Objective-C上处理图像。开发该软件的目的是带来与Adobe Photoshop用户相同的功能。示例:使用RGB 0-255设置颜色,应用混合滤镜,变换...

是开源的,这里是项目链接: https : //sourceforge.net/projects/photoshopframew/

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号