Objective-Cのカテゴリの仕組みを使うと、
@interface NSArray (Shuffle)
- (NSArray *)shuffle;
@end
下記のように実装しておけば、
@implementation NSArray (Shuffle)
- (NSArray *)shuffle {
// NSArray の要素をシャッフルするコード
}
@end
あとはヘッダファイルをimportするだけでshuffleというメソッドがNSArrayのオブジェクトから使用できるようになります。
このように、
今回はその中でも実装の面倒な部分をうまくラップしてくれているものを中心に3つほどカテゴリを紹介します。
UIImageに各種画像処理機能を持たせるNYXImagesKit
UIImageのカテゴリといえばリサイズ、
-(UIImage*)gaussianBlurWithBias:(NSInteger)bias;
-(UIImage*)redEyeCorrection;
-(UIImage*)brightenWithValue:(float)factor;
-(UIImage*)contrastAdjustmentWithValue:(float)value;
-(UIImage*)edgeDetectionWithBias:(NSInteger)bias;
-(UIImage*)embossWithBias:(NSInteger)bias;
-(UIImage*)gammaCorrectionWithValue:(float)value;
-(UIImage*)grayscale;
-(UIImage*)invert;
-(UIImage*)opacity:(float)value;
-(UIImage*)sepia;
-(UIImage*)sharpenWithBias:(NSInteger)bias;
-(UIImage*)unsharpenWithBias:(NSInteger)bias;
各ヘッダからメソッド定義の一部を抜粋
中でもブラーやエンボス等の畳み込み演算を伴う処理では、
/// vImage (iOS 5)
if ((&vImageConvolveWithBias_ARGB8888))
{
const size_t n = sizeof(UInt8) * width * height * 4;
void* outt = malloc(n);
vImage_Buffer src = {data, height, width, bytesPerRow};
vImage_Buffer dest = {outt, height, width, bytesPerRow};
vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_gaussianblur_kernel_5x5, 5, 5, 256/*divisor*/, bias, NULL, kvImageCopyInPlace);
memcpy(data, outt, n);
free(outt);
}
else
{
const size_t pixelsCount = width * height;
const size_t n = sizeof(float) * pixelsCount;
float* dataAsFloat = malloc(n);
float* resultAsFloat = malloc(n);
/// Red components
vDSP_vfltu8(data + 1, 4, dataAsFloat, 1, pixelsCount);
vDSP_f5x5(dataAsFloat, height, width, __f_gaussianblur_kernel_5x5, resultAsFloat);
vDSP_vfixu8(resultAsFloat, 1, data + 1, 4, pixelsCount);
/// Green components
vDSP_vfltu8(data + 2, 4, dataAsFloat, 1, pixelsCount);
vDSP_f5x5(dataAsFloat, height, width, __f_gaussianblur_kernel_5x5, resultAsFloat);
vDSP_vfixu8(resultAsFloat, 1, data + 2, 4, pixelsCount);
/// Blue components
vDSP_vfltu8(data + 3, 4, dataAsFloat, 1, pixelsCount);
vDSP_f5x5(dataAsFloat, height, width, __f_gaussianblur_kernel_5x5, resultAsFloat);
vDSP_vfixu8(resultAsFloat, 1, data + 3, 4, pixelsCount);
free(resultAsFloat);
free(dataAsFloat);
}
vImage、
Accelerateフレームワークは、
iPhoneやiPod touch用に最適化された何百もの数学関数を提供します。信号処理ルーチン、 高速フーリエ変換、 基本的なベクトルと行列演算、 およびマトリクス因数分解や連立一次方程式の解を求めるための業界標準機能などを含みます。iOSベースのデバイスに存在する異なるハードウェアコンフィギュレーション向けに最適化されたAccelerateフレームワークにより、 すべてのデバイスに効率的に動作するコードを書くことができます。
Features - iOS Technology Overview - Apple Developer
つまり簡単に言うと、
その中のvImageは畳み込みや幾何変換、
また vDSP にはベクタ演算や行列演算、
ここで紹介しているブラー等の画像処理で必要な畳み込み演算では、
ちなみにWWDC2011の
その他、
const size_t pixelsCount = width * height;
float* dataAsFloat = (float*)malloc(sizeof(float) * pixelsCount);
float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue;
UInt8* dataRed = data + 1;
// 中略
vDSP_vfltu8(dataRed, 4, dataAsFloat, 1, pixelsCount);
vDSP_vsmsa(dataAsFloat, 1, &__negativeMultiplier, &max, dataAsFloat, 1, pixelsCount);
vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount);
vDSP_vfixu8(dataAsFloat, 1, dataRed, 4, pixelsCount);
また、
NYXImagesKitはこちらからダウンロードできます
なお、
- Accelerate.
framework - AsetsLibrary.
framework - CoreImage.
framework - ImageIO.
framework - libcommonCrypto.
dylib - MobileCoreServices.
framework
NYXImagesKitにはサンプルアプリが付随していないため、
デモアプリを実行すると、

これらの画像処理のいずれもNYXImagesKitを使用したったの1行で実装されています。
画像処理を行いたい場合にはOpenCV等の選択肢もありますが、
面倒なデリゲート処理を Blocks で記述できるカテゴリ
たとえば、
- プロトコルへの準拠を宣言する
- delegate プロパティに値をセット
- 表示処理を実装
- デリゲートメソッドを実装
書き出してみるとこれだけのことではあるのですが、
感じるところは皆同じらしく、
たとえば UIKitCategoryAdditions というカテゴリを使用すると、
- 表示処理を実装
これだけになります。表示処理自体もオブジェクトの生成や表示メソッドのコールをラップしてくれているので、
[UIActionSheet actionSheetWithTitle:@"Sample"
message:@"Hello World"
destructiveButtonTitle:@"Cancel"
buttons:[NSArray arrayWithObjects:@"First", @"Second", nil]
showInView:self.view
onDismiss:^(int buttonIndex) {
// キャンセル以外のボタンが押された場合の処理
NSLog(@"%d", buttonIndex);
}
onCancel:^ {
// キャンセルボタンが押された場合の処理
NSLog(@"Cancelled");
}];
また、
この一連のフローを実装するとそこそこのステップ数になりますが、
[UIActionSheet photoPickerWithTitle:@"Choose an image"
showInView:self.view
presentVC:self
onPhotoPicked:^(UIImage* image) {
// 画像が選択された場合の処理
NSLog(@"%@", image);
}
onCancel:^ {
// キャンセルされた場合の処理
NSLog(@"Cancelled");
}];
……と、
static DismissBlock _dismissBlock;
static CancelBlock _cancelBlock;
+ (void) actionSheetWithTitle:(NSString*) title
message:(NSString*) message
destructiveButtonTitle:(NSString*) destructiveButtonTitle
buttons:(NSArray*) buttonTitles
showInView:(UIView*) view
onDismiss:(DismissBlock) dismissed
onCancel:(CancelBlock) cancelled
{
[_cancelBlock release];
_cancelBlock = [cancelled copy];
[_dismissBlock release];
_dismissBlock = [dismissed copy];
// 後略
このようにstatic変数にBlockをcopyして保持しており、
インスタンス変数に保持するようにした場合、
このUIKitCategoryAdditionsだけでなく、
そして、
Block内でそのBlockを保持するオブジェクト自身を強参照すると、
id __weak hoge = self;
上で紹介したUIKitCategoryAdditionsにも、
有名なOSSなので利用者も多く、
日本語での解説記事もいくつかあるので本連載では解説は省略しますが、
英単語の単数形/複数形変換をメソッド1つで行えるようにするNSStringのカテゴリ
iOSアプリを英語ローカライズする際、
それら諸々のルールをプロパティリストファイルに記述し、
- (NSString *)pluralizeString;
- (NSString *)singularizeString;
このように非常にシンプルなメソッドで単数/複数変換を行えるようにしたカテゴリがActiveSupportInflectorです。
ダウンロード先は下記になります
使用にあたってはNSString+ActiveSupportInflectorクラス以外に、
ちなみに、
//#import "NSString+MSAdditions.h"
このNSString+MSAdditions.
このカテゴリによってどんな変換ができるようになるかは、
("search", "searches"),
("stack", "stacks"),
("fish", "fish"),
("category", "categories"),
("ability", "abilities"),
("agency", "agencies"),
("index", "indices"),
("wife", "wives"),
("safe", "saves"),
("half", "halves"),
("person", "people"),
("man", "men"),
("woman", "women"),
("basis", "bases"),
まとめ
UIImageに各種画像処理機能を持たせるNYXImagesKit、
今回は記事の都合上3つしか紹介できませんでしたが、