87

カラーリファレンスで画像に色を付けたいのですが。結果は、Photoshopの乗算ブレンドモードのようになります。このモードでは、白が色合いに置き換えられます。

代替テキスト

色の値を継続的に変更していきます。

フォローアップ:これを行うためのコードをImageViewのdrawRect:メソッドに入れますよね?

いつものように、コードスニペットは、リンクではなく、私の理解に大いに役立ちます。

更新:Raminが提案したコードでUIImageViewをサブクラス化します。

私はこれを私のviewcontrollerのviewDidLoad:に入れました:

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

画像は見えますが、色が付いていません。また、他の画像を読み込んで、IBで画像を設定し、View ControllerでsetNeedsDisplay:を呼び出してみました。

更新:drawRect:が呼び出されていません。

最終更新: Raminのコードをテストできるように、imageViewが適切に設定されている古いプロジェクトを見つけました。これは、魅力のように機能します。

最終、最終更新:

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
}
4

13 に答える 13

77

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
于 2013-10-01T20:18:11.507 に答える
45

まず、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から継承)を画像とoverlayColorUIColor値に設定します(ブレンドレベルは、渡す色のアルファ値を変更することで調整できます)。

于 2009-07-13T06:54:07.453 に答える
26

簡単な説明(このトピックに関するいくつかの調査の後)。ここにあるAppleのドキュメントには、次のように明確に記載されています。

このUIImageViewクラスは、画像をディスプレイに描画するように最適化されています。そのサブクラスUIImageViewのメソッドを呼び出しません。drawRect:サブクラスにカスタム描画コードを含める必要がある場合は、UIView代わりにクラスをサブクラス化する必要があります。

UIImageViewしたがって、サブクラスでそのメソッドをオーバーライドしようとしても時間を無駄にしないでください。UIView代わりにから始めてください。

于 2010-05-27T15:51:49.410 に答える
26

画像をアルファで着色したかったので、次のクラスを作成しました。問題があれば教えてください。

以前の返信で述べたように、クラスに名前を付けましたが、メソッドを呼び出さないため、クラスはからCSTintedImageView継承します。クラスにあるものと同様の指定された初期化子を設定しました。UIViewUIImageViewdrawRect: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
于 2011-12-02T04:30:12.080 に答える
5

これは非常に便利です。PhotoshopFrameworkは、Objective-Cで画像を操作するための強力なライブラリの1つです。これは、AdobePhotoshopユーザーが使い慣れているのと同じ機能を提供するために開発されました。例:RGB 0〜255を使用して色を設定し、ブレンドファイラー、変換を適用します。

オープンソースです。プロジェクトのリンクは次のとおりです:https ://sourceforge.net/projects/photoshopframew/

于 2009-10-22T20:44:16.320 に答える
4
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
于 2015-02-07T04:25:44.850 に答える
2

UIImageViewクラスをサブクラス化しようとして、「drawRect:が呼び出されていません」でスタックする場合は、代わりにUIViewクラスをサブクラス化する必要があることに注意してください。UIImageViewクラスの場合、「drawRect:」メソッドは呼び出されません。詳細はこちら:UIImageViewのサブクラスでdrawRectが呼び出されない

于 2010-11-25T20:58:43.183 に答える
2

特に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をプロジェクトのフレームワークリストに追加します(まだ存在しない場合)。そうしないと、次のようなコンパイラエラーが発生します。

Undefined symbols for architecture i386: "_OBJC_CLASS_$_CALayer"
于 2013-09-14T18:48:46.797 に答える
0

私が考えることができる唯一のことは、希望の色で長方形のほぼ透明なビューを作成し、それをサブビューとして追加して画像ビューの上に置くことです。これが本当にあなたが想像する方法で画像に色を付けるかどうかはわかりませんが、画像をハックして特定の色を他の色に選択的に置き換える方法はわかりません...私にはかなり野心的に聞こえます。

例えば:

UIImageView *yourPicture = (however you grab the image);
UIView *colorBlock = [[UIView alloc] initWithFrame:yourPicture.frame];
//Replace R G B and A with values from 0 - 1 based on your color and transparency
colorBlock.backgroundColor = [UIColor colorWithRed:R green:G blue:B alpha:A];
[yourPicture addSubView:colorBlock];

UIColorのドキュメント:

colorWithRed:green:blue:alpha:

Creates and returns a color object using the specified opacity and RGB component values.

+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha

Parameters

red    - The red component of the color object, specified as a value from 0.0 to 1.0.

green  - The green component of the color object, specified as a value from 0.0 to 1.0.

blue   - The blue component of the color object, specified as a value from 0.0 to 1.0.



alpha  - The opacity value of the color object, specified as a value from 0.0 to 1.0.

Return Value

The color object. The color information represented by this object is in the device RGB colorspace. 
于 2009-07-13T02:26:08.250 に答える
0

また、パフォーマンスのために合成画像をキャッシュし、drawRect:でレンダリングすることを検討し、ダーティフラグが実際にダーティである場合は更新することもできます。頻繁に変更する場合もありますが、ドローが入って汚れていない場合もあるので、キャッシュから簡単に更新できます。メモリがパフォーマンスよりも問題である場合は、これを無視してかまいません:)

于 2009-07-13T16:21:24.427 に答える
0

私はこれのためにオープンソースしたライブラリを持っています:ios-image-filters

于 2011-08-27T07:42:37.690 に答える
0

Swift 2.0の場合、

    let image: UIImage! = UIGraphicsGetImageFromCurrentImageContext()

    imgView.image = imgView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)

    imgView.tintColor = UIColor(red: 51/255.0, green: 51/255.0, blue: 

51/255.0, alpha: 1.0)
于 2016-03-01T11:03:58.633 に答える
0

私はこの目的のためにマクロを作成しました:

#define removeTint(view) \
if ([((NSNumber *)[view.layer valueForKey:@"__hasTint"]) boolValue]) {\
for (CALayer *layer in [view.layer sublayers]) {\
if ([((NSNumber *)[layer valueForKey:@"__isTintLayer"]) boolValue]) {\
[layer removeFromSuperlayer];\
break;\
}\
}\
}

#define setTint(view, tintColor) \
{\
if ([((NSNumber *)[view.layer valueForKey:@"__hasTint"]) boolValue]) {\
removeTint(view);\
}\
[view.layer setValue:@(YES) forKey:@"__hasTint"];\
CALayer *tintLayer = [CALayer new];\
tintLayer.frame = view.bounds;\
tintLayer.backgroundColor = [tintColor CGColor];\
[tintLayer setValue:@(YES) forKey:@"__isTintLayer"];\
[view.layer addSublayer:tintLayer];\
}

使用するには、次の電話をかけるだけです。

setTint(yourView, yourUIColor);
//Note: include opacity of tint in your UIColor using the alpha channel (RGBA), e.g. [UIColor colorWithRed:0.5f green:0.0 blue:0.0 alpha:0.25f];

色合いを取り除くときは、単に次のように呼び出します。

removeTint(yourView);
于 2018-06-21T04:17:10.087 に答える