1. ホーム
  2. iphone

iPhoneで透明なPNG画像を着色する方法は?

2023-12-16 12:29:22

質問

矩形の画像にCGContextFillRectを描画してブレンドモードを設定することで、色合いをつけることが可能なのは知っています。しかし、アイコンのような透明な画像に色合いを行う方法を見つけ出すことができません。タブバーなどではSDKが勝手にやってくれるので可能なのでしょうが。誰もがスニペットを提供することができるでしょうか?

UPDATE。

私が最初に質問してから、この問題に対してたくさんの素晴らしい提案がなされました。すべての回答に目を通して、自分に最も適したものを見つけ出してください。

UPDATE (2015年4月30日):

iOS 7.0では、以下のようにすれば、当初の質問のニーズを満たせるようになりました。しかし、もっと複雑なケースがある場合は、すべての回答をチェックしてください。

UIImage *iconImage = [[UIImage imageNamed:@"myImageName"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];    
UIImageView *icon = [[UIImageView alloc] initWithImage:iconImage];
icon.tintColor = [UIColor redColor];

どのように解決するのですか?

更新しました。 以下は 要旨 で、以下のコードを使ってSwift UIColor拡張を行います。


もしあなたが グレースケールイメージ があり 白を着色色にしたい , kCGBlendModeMultiply という方法があります。この方法では、ティントカラーよりも明るいハイライトを入れることはできません。

逆に、もしあなたがどちらかの グレースケールでない画像 , または をお持ちの場合 ハイライト シャドウ を保存する必要があり、ブレンドモード kCGBlendModeColor が適しています。画像の明るさが保たれるので、白は白のまま、黒は黒のままです。このモードはまさに色調補正のために作られたもので、Photoshopの Color レイヤーブレンドモードと同じです(免責事項:若干異なる結果が発生する可能性があります)。

アルファピクセルの色付けは、iOS でも Photoshop でも正しく動作しないことに注意してください - 半透明の黒いピクセルは黒いままではありません。この問題を解決するために、以下の回答を更新しました。

また、ブレンドモードの1つを使用することもできます。 kCGBlendModeSourceIn/DestinationIn の代わりに CGContextClipToMask .

を作成したい場合は UIImage のように、それぞれを以下のようなコードで囲むことができます。

UIGraphicsBeginImageContextWithOptions (myIconImage.size, NO, myIconImage.scale); // for correct resolution on retina, thanks @MobileVet
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextTranslateCTM(context, 0, myIconImage.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGRect rect = CGRectMake(0, 0, myIconImage.size.width, myIconImage.size.height);

// image drawing code here

UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


で透明な画像を着色するコードは以下のとおりです。 kCGBlendModeColor :

// draw black background to preserve color of transparent pixels
CGContextSetBlendMode(context, kCGBlendModeNormal);
[[UIColor blackColor] setFill];
CGContextFillRect(context, rect);

// draw original image
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);

// tint image (loosing alpha) - the luminosity of the original image is preserved
CGContextSetBlendMode(context, kCGBlendModeColor);
[tintColor setFill];
CGContextFillRect(context, rect);

// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);

画像に半透明なピクセルがない場合は、その逆で kCGBlendModeLuminosity :

// draw tint color
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);

// replace luminosity of background (ignoring alpha)
CGContextSetBlendMode(context, kCGBlendModeLuminosity);
CGContextDrawImage(context, rect, myIconImage.CGImage);

// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);


アルファチャンネルを持つ画像を色で染めるだけなので、輝度を気にしないのであれば、より効率的な方法でそれを行うことができます。

// draw tint color
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);

// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);

またはその逆

// draw alpha-mask
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);

// draw tint color, preserving alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[tintColor setFill];
CGContextFillRect(context, rect);

楽しんでください。