UIImageにブレンドモードを指定して加工する方法

Objective-Cで UIImageにブレンドモードを指定し表示するサンプルを以下に作成しました。

カメラアプリの実験用に Photoshopのように画像を重ねてブレンド表示する方法を色々試しましたので、以下に詳細を記載します。

サンプルダウンロード

使用する画像

元画像

重ねて表示する画像

結果画像(ブレンドモード: スクリーン)

ブレンドモードの種類

CGBlendMode 説明
kCGBlendModeMultiply 乗算
kCGBlendModeScreen スクリーン
kCGBlendModeOverlay オーバーレイ
kCGBlendModeDarken 比較(暗)
kCGBlendModeLighten 比較(明)
kCGBlendModeColorDodge 覆い焼きカラー
kCGBlendModeColorBurn 焼きこみカラー
kCGBlendModeSoftLight ソフトライト
kCGBlendModeHardLight ハードライト
kCGBlendModeDifference 差の絶対値
kCGBlendModeExclusion 除外
kCGBlendModeHue 色相
kCGBlendModeSaturation 彩度
kCGBlendModeColor カラー
kCGBlendModeLuminosity 輝度
kCGBlendModeClear 透明色で描画

ソースコード

ViewController.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#import <UIKit/UIKit.h>

#define BACK_IMAGE              @"blend_image.png"
#define BACK_IMAGE_WIDTH        640
#define BACK_IMAGE_HEIGHT       1136
#define FRONT_IMAGE             @"Asymmetry_640_1136.jpg"
#define FRONT_IMAGE_WIDTH       640
#define FRONT_IMAGE_HEIGHT      1136
#define FRONT_IMAGE_ALPHA       1.0f
#define PREVIEW_IMAGE_WIDTH     80
#define PREVIEW_IMAGE_HEIGHT    142
#define BLEND_MODE_LABEL_HEIGHT 20

@interface BlendMode : UIView {
@private
    UIImage     *frontImage_;
    UIImage     *backImage_;
    CGBlendMode blendMode_;
}

@property (nonatomic, assign) CGBlendMode blendMode;

- (void)changeMode;

@end

@interface ViewController : UIViewController {
@private
    BlendMode *blendMode_;
    UILabel   *blendModeLabel_;
}

@end

ViewController.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#import "ViewController.h"

@implementation BlendMode

@synthesize blendMode = blendMode_;

- (id)init
{
    if (self = [super init]) {
        backImage_ = [UIImage imageNamed:BACK_IMAGE];
        frontImage_ = [UIImage imageNamed:FRONT_IMAGE];
        CGRect newFrame = self.frame;
        newFrame.size = frontImage_.size;
        self.frame = newFrame;
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    [backImage_ drawInRect:rect];
    [frontImage_ drawInRect:rect blendMode:blendMode_ alpha:FRONT_IMAGE_ALPHA];
}

- (void)changeMode
{
    if (kCGBlendModeLuminosity < ++blendMode_) {
        blendMode_ = kCGBlendModeNormal;
    }
}

@end

#pragma mark private methods definition

@interface ViewController ()

- (void)changeLabel;

@end

#pragma mark start implementation for methods

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //初期化
    blendMode_ = [[BlendMode alloc] init];
    blendMode_.center = self.view.center;
    blendMode_.autoresizingMask =
        UIViewAutoresizingFlexibleTopMargin |
        UIViewAutoresizingFlexibleBottomMargin;
    [self.view addSubview:blendMode_];

    //重ねて表示するイメージ表示
    UIImage *imageBack = [UIImage imageNamed:BACK_IMAGE];
    UIImageView *imageViewBack = [[UIImageView alloc] initWithImage:imageBack];
    imageViewBack.frame = CGRectMake(0, 0, BACK_IMAGE_WIDTH, BACK_IMAGE_HEIGHT);
    imageViewBack.autoresizingMask =
        UIViewAutoresizingFlexibleLeftMargin |
        UIViewAutoresizingFlexibleRightMargin |
        UIViewAutoresizingFlexibleTopMargin |
        UIViewAutoresizingFlexibleBottomMargin;
    [self.view addSubview:imageViewBack];

    //プレビューイメージ表示
    UIImage *imageFront = [UIImage imageNamed:FRONT_IMAGE];
    UIImageView *imageViewFront = [[UIImageView alloc] initWithImage:imageFront];
    imageViewFront.frame = CGRectMake(320 - PREVIEW_IMAGE_WIDTH,
                                      0,
                                      PREVIEW_IMAGE_WIDTH,
                                      PREVIEW_IMAGE_HEIGHT);
    imageViewFront.autoresizingMask = imageViewFront.autoresizingMask;
    [self.view addSubview:imageViewFront];

    //ブレンドモードを変更するラベル表示
    blendModeLabel_ = [[UILabel alloc] init];
    blendModeLabel_.frame = CGRectMake(0,
                                       self.view.bounds.size.height - BLEND_MODE_LABEL_HEIGHT,
                                       self.view.bounds.size.width,
                                       BLEND_MODE_LABEL_HEIGHT);
    blendModeLabel_.autoresizingMask =
        UIViewAutoresizingFlexibleTopMargin |
        UIViewAutoresizingFlexibleBottomMargin;
    blendModeLabel_.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:blendModeLabel_];

    //ラベル変更
    [self changeLabel];
}

#pragma mark private methods

- (void)changeLabel {
    switch (blendMode_.blendMode) {
        case kCGBlendModeMultiply:        blendModeLabel_.text = @"kCGBlendModeMultiply"; break;        /* 乗算 */
        case kCGBlendModeScreen:          blendModeLabel_.text = @"kCGBlendModeScreen"; break;          /* スクリーン */
        case kCGBlendModeOverlay:         blendModeLabel_.text = @"kCGBlendModeOverlay"; break;         /* オーバーレイ */
        case kCGBlendModeDarken:          blendModeLabel_.text = @"kCGBlendModeDarken"; break;          /* 比較(暗) */
        case kCGBlendModeLighten:         blendModeLabel_.text = @"kCGBlendModeLighten"; break;         /* 比較(明) */
        case kCGBlendModeColorDodge:      blendModeLabel_.text = @"kCGBlendModeColorDodge"; break;      /* 覆い焼きカラー */
        case kCGBlendModeColorBurn:       blendModeLabel_.text = @"kCGBlendModeColorBurn"; break;       /* 焼きこみカラー */
        case kCGBlendModeSoftLight:       blendModeLabel_.text = @"kCGBlendModeSoftLight"; break;       /* ソフトライト */
        case kCGBlendModeHardLight:       blendModeLabel_.text = @"kCGBlendModeHardLight"; break;       /* ハードライト */
        case kCGBlendModeDifference:      blendModeLabel_.text = @"kCGBlendModeDifference"; break;      /* 差の絶対値 */
        case kCGBlendModeExclusion:       blendModeLabel_.text = @"kCGBlendModeExclusion"; break;       /* 除外 */
        case kCGBlendModeHue:             blendModeLabel_.text = @"kCGBlendModeHue"; break;             /* 色相 */
        case kCGBlendModeSaturation:      blendModeLabel_.text = @"kCGBlendModeSaturation"; break;      /* 彩度 */
        case kCGBlendModeColor:           blendModeLabel_.text = @"kCGBlendModeColor"; break;           /* カラー */
        case kCGBlendModeLuminosity:      blendModeLabel_.text = @"kCGBlendModeLuminosity"; break;      /* 輝度 */
        case kCGBlendModeClear:           blendModeLabel_.text = @"kCGBlendModeClear"; break;           /* 透明色で描画 */
        case kCGBlendModeCopy:            blendModeLabel_.text = @"kCGBlendModeCopy"; break;            /* コピー */
        case kCGBlendModeSourceIn:        blendModeLabel_.text = @"kCGBlendModeSourceIn"; break;
        case kCGBlendModeSourceOut:       blendModeLabel_.text = @"kCGBlendModeSourceOut"; break;
        case kCGBlendModeSourceAtop:      blendModeLabel_.text = @"kCGBlendModeSourceAtop"; break;
        case kCGBlendModeDestinationOver: blendModeLabel_.text = @"kCGBlendModeDestinationOver"; break;
        case kCGBlendModeDestinationIn:   blendModeLabel_.text = @"kCGBlendModeDestinationIn"; break;
        case kCGBlendModeDestinationOut:  blendModeLabel_.text = @"kCGBlendModeDestinationOut"; break;
        case kCGBlendModeDestinationAtop: blendModeLabel_.text = @"kCGBlendModeDestinationAtop"; break;
        case kCGBlendModeXOR:             blendModeLabel_.text = @"kCGBlendModeXOR"; break;
        case kCGBlendModePlusDarker:      blendModeLabel_.text = @"kCGBlendModePlusDarker"; break;
        case kCGBlendModePlusLighter:     blendModeLabel_.text = @"kCGBlendModePlusLighter"; break;
        default:                          blendModeLabel_.text = @"kCGBlendModeNormal"; break;
    }
}

#pragma mark responder

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    //ブレンドモード変更
    [blendMode_ changeMode];

    //ラベルの変更
    [self changeLabel];

    //ブレンド実行
    [blendMode_ setNeedsDisplay];
}

@end

お薦めの参考書

Swiftポケットリファレンス
Swiftの基本的な使い方から、データ処理やネットワーク処理の応用まで、逆引き形式で調べられる良書です。サンプルコードも Webからダウンロード出来、とても便利です。内容としては中級者向けですが、手元にあれば安心の一冊です。

   このエントリーをはてなブックマークに追加

About

Masaki Hirokawa (@dolice_apps)

デザインエンジニア 廣川政樹の開発ブログ。Objective-Cや Javaなど iPhone/Androidアプリ開発に関する技術情報を掲載しています。

iPhone apps

  • リラックス・ヒーリング(無料)
  • 望みが叶う!引き寄せの法則アプリ(無料)
  • ミステリー - 怖い話や不思議な体験、都市伝説まとめ
  • 浮世絵壁紙 - 美しい日本画ギャラリー(無料)
  • 綺麗な壁紙HD iPhone 7/7 Plus/SE & iPod対応(無料)
  • クールな壁紙HD iPhone 7/7 Plus/SE & iPod対応(無料)

Android apps

  • 浮世絵壁紙 - 美しい日本画ギャラリー
  • 綺麗な高画質壁紙

Objective-C Classes

Tag Cloud

ActionScript(9) ActionScript3(7) Ad(4) Adfurikun(2) AdMob(9) Android(10) Animation(17) AppDelegate(3) ARC(1) ArrayList(1) AVAudioPlayer(4) AVAudioSession(1) AVFoundation(3) Banner(2) Bitmap(1) Camera(4) CGAffineTransform(4) CGBlendMode(2) CGContextRef(1) CGImageRef(1) Classes(44) CLLocationManager(1) ConnectivityManager(1) ContentResolver(1) CoreLocation(2) Delegate(3) Device(7) Display(1) DisplayMetrics(1) Download(101) Facebook(6) Foundation(72) Framework(2) Google Analytics(1) Handler(1) iAd(6) ImageView(1) In-AppPurchase(1) iOS(12) iOS 7(15) iOS 7.1(3) iOS 8(1) iPad(7) iPhone(21) iPhone 6(4) Java(7) JavaScript(2) LINE(4) Localize(1) Magazine(1) MediaStore(1) MFComposeViewController(1) Nend(1) NetworkInfo(1) NSArray(23) NSCalendar(3) NSData(2) NSDate(7) NSDateComponents(2) NSDateFormatter(2) NSDictionary(12) NSEnumerator(1) NSIndexSet(1) NSInteger(6) NSMutableArray(17) NSMutableDictionary(5) NSMutableOrderedSet(7) NSMutableString(4) NSMutableURLRequest(1) NSNotificationCenter(1) NSNumber(1) NSObject(1) NSOrderedSet(7) NSRange(2) NSSelectorFromString(1) NSSet(6) NSString(19) NSTimer(4) NSTimeZone(1) NSURL(7) NSURLConnection(1) NSURLRequest(2) NSUserDefaults(7) NSXMLParser(2) Objective-C(222) PHP(1) Products(14) QuartzCore(3) RSS(2) Runnable(1) Sample(51) Screensaver(9) SDK(2) ShareCompat(1) Social(10) StoreKit(1) Twitter(6) UIAccelerometer(3) UIActionSheet(1) UIActivityIndicator(1) UIActivityIndicatorView(3) UIActivityViewController(1) UIAlertView(5) UIApplication(7) UIButton(4) UIColor(3) UIDatePicker(5) UIDevice(6) UIDeviceOrientation(1) UIEvent(6) UIImage(15) UIImagePickerController(4) UIImageView(12) UIKit(58) UILabel(7) UINavigationBar(4) UINavigationItem(1) UIPasteboard(4) UIScreen(1) UIScrollBar(1) UIScrollView(1) UISlider(3) UIStoryboardSegue(3) UISwitch(1) UITabBar(3) UITableView(4) UITextField(2) UIView(11) UIViewAnimationTransition(1) UIViewController(4) UIWebView(5) WindowManager(1) Xcode(48) Xcode 5(8) Xcode 5.1(2)