Objective-C Tab + 画像エフェクト処理

Tabを使用した切り替え画像表示と画像エフェクト処理をした表示。

AppDelegate.h

#import <UIKit/UIKit.h>


@interface AppDelegate : UIResponder <UIApplicationDelegate>


@property (strong, nonatomic) UIWindow *window;


// 画像インデックス番号(アプリ共通)

// AppDelegateに変数をおいておくとどのクラスからもアクセスしやすくて便利

@property (assign, nonatomic) int idxImage;


// 画像の取得

- (UIImage *)getImage;


@end

AppDelegate.m

#import "AppDelegate.h"


@implementation AppDelegate


- (BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    // Override point for customization after application launch.

    

    // 画像インデックス番号初期化

    self.idxImage = 0;

    

    return YES;

}

- (void)applicationWillResignActive:(UIApplication *)application

{


}


- (void)applicationDidEnterBackground:(UIApplication *)application

{


}


- (void)applicationWillEnterForeground:(UIApplication *)application

{


}


- (void)applicationDidBecomeActive:(UIApplication *)application

{


}


- (void)applicationWillTerminate:(UIApplication *)application

{


}


#pragma mark - Own Method


// 画像ファイルの取得

- (UIImage *)getImage {

    

    NSString *str = [NSString stringWithFormat:

                     @"Image%02d.png",self.idxImage];

    UIImage *img = [UIImage imageNamed:str];

    

    //return [UIImage imageNamed:str];

    

    return img;

}


@end

ViewController01.m

#import "ViewController01.h"

//#import "AppDelegate.h" // pchファイルで記述


@interface ViewController01 ()


@property (weak, nonatomic) IBOutlet UIImageView *ivImage;


@end


@implementation ViewController01


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [super viewDidLoad];

    // Do any additional setup after loading the view.

}


- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


// ビューの表示前 delegateを使って画像を読んでいる

- (void)viewWillAppear:(BOOL)animated {

    

    [super viewWillAppear:animated];

    

    // 画像表示

    AppDelegate *ad = [UIApplication sharedApplication].delegate;

    self.ivImage.image = [ad getImage];

    

//    NSString *str = [NSString stringWithFormat:@"Image0%d.png", ad.idxImage];

//    

//    self.ivImage.image = [UIImage imageNamed:str];

    

}


/*

#pragma mark - Navigation


// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/


// 画像変更セグメント変更時 %02d

- (IBAction)selectSegmented:(UISegmentedControl *)sender {


    //NSLog(@"%ld, %@", (long)sender.tag, str);

    

    // AppDelegateに宣言した変数に別クラスからアクセスする方法

    // AppDelegateに画像インデックス番号退避

    AppDelegate *ad = [UIApplication sharedApplication].delegate;

    ad.idxImage = sender.selectedSegmentIndex;

    

    // 画像の表示

//    NSString *str = [NSString stringWithFormat:@"Image0%d.png", sender.selectedSegmentIndex];

//    self.ivImage.image = [UIImage imageNamed:str];

    

    // 画像の表示

    self.ivImage.image = [ad getImage];

    

    // ①バッチ表示

    self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d", ad.idxImage];


}

@end

ViewController02.m

#import "ViewController02.h"


@interface ViewController02 ()


@property (weak, nonatomic) IBOutlet UIImageView *ivImage;


@end


@implementation ViewController02


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [super viewDidLoad];

    // Do any additional setup after loading the view.

}


- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


// ビューの表示前

- (void)viewWillAppear:(BOOL)animated {

    

    [super viewWillAppear:animated];

    

    // 画像表示

    //AppDelegate *ad = [UIApplication sharedApplication].delegate;

    

    //NSString *str = [NSString stringWithFormat:@"Image0%d.png", ad.idxImage];

    

    //self.ivImage.image = [UIImage imageNamed:str];

    

    // AppDelegateに宣言した変数に別クラスからアクセスする方法

    // AppDelegateに画像インデックス番号退避

    AppDelegate *ad = [UIApplication sharedApplication].delegate;

    

    //self.ivImage.image = [ad getImage];

    

    // ImageEffect クラス + applyGrayscale: メソッド

    self.ivImage.image = [ImageEffect applyGrayscale:[ad getImage]];

    

}


/*

#pragma mark - Navigation


// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/


@end

ViewController03.m

#import "ViewController03.h"


@interface ViewController03 ()


@property (weak, nonatomic) IBOutlet UIImageView *ivImage;


@end


@implementation ViewController03


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [super viewDidLoad];

    // Do any additional setup after loading the view.

}


- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


// ビューの表示前

- (void)viewWillAppear:(BOOL)animated {

    

    [super viewWillAppear:animated];

    

    // 画像表示

//    AppDelegate *ad = [UIApplication sharedApplication].delegate;

//    

//    NSString *str = [NSString stringWithFormat:@"Image0%d.png", ad.idxImage];

//    

//    self.ivImage.image = [UIImage imageNamed:str];

    

    // AppDelegateに宣言した変数に別クラスからアクセスする方法

    // AppDelegateに画像インデックス番号退避

    AppDelegate *ad = [UIApplication sharedApplication].delegate;

    //self.ivImage.image = [ad getImage];

    

    // ImageEffect セピアクラス + applyGrayscale: メソッド

    self.ivImage.image = [ImageEffect applySepia:[ad getImage]];

    

}



/*

#pragma mark - Navigation


// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/


@end

ImageEffect.h

#import <Foundation/Foundation.h>


@interface ImageEffect : NSObject


// 画像のグレースケール化

+ (UIImage *)applyGrayscale:(UIImage *)targetImage;

// 画像のセピア化

+ (UIImage *)applySepia:(UIImage *)targetImage;


@end

ImageEffect.m

#import "ImageEffect.h"


enum {

GRAY_SCALE,

SEPIA

};


@implementation ImageEffect


// 画像のグレースケール化

+ (UIImage *)applyGrayscale:(UIImage *)targetImage

{

return [ImageEffect applyEffect:targetImage

effect:GRAY_SCALE];

}


// 画像のセピア化

+ (UIImage *)applySepia:(UIImage *)targetImage

{

return [ImageEffect applyEffect:targetImage

effect:SEPIA];

}


// 画像への効果適用

+ (UIImage *)applyEffect:(UIImage *)anImage

  effect:(int)effect

{

//--------------------------------------------

// 画像情報の取得

//--------------------------------------------

CGImageRef imr = anImage.CGImage;

// (幅、高さ)

size_t width  = CGImageGetWidth(imr);

size_t height = CGImageGetHeight(imr);

// NSLog(@"%ld, %ld", cgWidth, cgHeight);

// (RGBα各要素の構成ビット)

//  1バイト = 8ビット

size_t bitsPerComponent = CGImageGetBitsPerComponent(imr);

// NSLog(@"%ld", bitsPerComponent);

// (ピクセル全体の構成ビット)

//  8ビットがRGBA分:8 x 4 = 32ビット

size_t bitsPerPixel = CGImageGetBitsPerPixel(imr);

// NSLog(@"%ld", bitsPerPixel);

// (1ライン分のデータの構成バイト)

//  width x 4

size_t bytesPerRow = CGImageGetBytesPerRow(imr);

// NSLog(@"%ld", bytesPerRow);

// (色空間)

CGColorSpaceRef colorSpace = CGImageGetColorSpace(imr);

// (Bitmap情報)

CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imr);

// (画像のピクセル間補完の有無)

bool shouldInterpolate = CGImageGetShouldInterpolate(imr);

// (表示装置による補正)

CGColorRenderingIntent intent = CGImageGetRenderingIntent(imr);

// (データプロバイダよりビットマップデータ)

CGDataProviderRef dp      = CGImageGetDataProvider(imr);

CFDataRef         data    = CGDataProviderCopyData(dp);

UInt8             *buffer = (UInt8 *)CFDataGetBytePtr(data);

// 1ピクセルずつ画像を処理

for (NSUInteger y = 0; y < height; y++) {

for (NSUInteger x = 0; x < width; x++) {

// RGBA4つ値をもっているので、1ピクセルごとに*4してずらす

UInt8 *tmp = buffer + y * bytesPerRow + x * 4;

// RGB値を取得

UInt8 red   = *(tmp + 0);

UInt8 green = *(tmp + 1);

UInt8 blue  = *(tmp + 2);

// 輝度計算

//RGBの各々の値の差をなくし、明るさ(輝度 y)の差だけにする。

//  y = (77 * r + 28 * g + 151 * b) / 256

UInt8 brightness = (77 * red + 28 * green + 151 * blue) / 256;

// エフェクト

switch (effect) {

case GRAY_SCALE:

*(tmp + 0) = brightness;

*(tmp + 1) = brightness;

*(tmp + 2) = brightness;

break;

case SEPIA:

*(tmp + 0) = brightness;

*(tmp + 1) = brightness * 0.7;

*(tmp + 2) = brightness * 0.4;

break;

default:

break;

}

}

}

// 効果を与えたデータ生成

CFDataRef effectedData =

CFDataCreate(NULL, buffer, CFDataGetLength(data));

// 効果を与えたデータプロバイダを生成

CGDataProviderRef effectedDataProvider =

CGDataProviderCreateWithCFData(effectedData);

// 画像を生成

CGImageRef effectedCgImage =

CGImageCreate(width,

  height,

  bitsPerComponent,

  bitsPerPixel,

  bytesPerRow,

  colorSpace,

  bitmapInfo,

  effectedDataProvider,

  NULL,

  shouldInterpolate,

  intent);

UIImage *ret = [UIImage imageWithCGImage:effectedCgImage];


// データの解放

CGImageRelease(effectedCgImage);

CFRelease(effectedDataProvider);

CFRelease(effectedData);

CFRelease(data);

return ret;

}


@end

GitHub Tab

▫️参考ページ


  

目 次