CoreImage リサイズ、画像中央から指定サイズでのトリミング


CoreImageを使用したリサイズと画像の中央からのトリミングです。

![ss1](http://f.cl.ly/items/0x0C2W0Y282F0Q3d3V05/resize-2.png)

![ss2](http://f.cl.ly/items/0P0V1g2b3k1z1O0s2v3Q/cropping-2.png)

## 実装

CoreImage.frameworkの追加は忘れずに。
外部ライブラリを使用しないので、手軽に利用できますね。

```objectivec:CoreImageHelper.h
@interface CoreImageHelper : NSObject

/* アスペクトサイズを維持してリサイズ */
+ (void)resizeAspectFitImageWithImage:(UIImage*)img atSize:(CGFloat)size completion:(void(^)(UIImage*))completion;

/* 画像の中央からトリミング */
+ (void)centerCroppingImageWithImage:(UIImage*)img atSize:(CGSize)size completion:(void(^)(UIImage*))completion;

/* CIImageからUIImageを作成 */
+ (UIImage*)uiImageFromCIImage:(CIImage*)ciImage;

@end
```

```objectivec:CoreImageHelper.m
@implementation CoreImageHelper

+ (void)resizeAspectFitImageWithImage:(UIImage*)img atSize:(CGFloat)size completion:(void(^)(UIImage*))completion
{
    CIImage *ciImage = [[CIImage alloc] initWithImage:img];
    // リサイズする倍率を求める
    CGFloat scale = img.size.width < img.size.height ? size/img.size.height : size/img.size.width;
    // CGAffineTransformでサイズ変更
    CIImage *filteredImage = [ciImage imageByApplyingTransform:CGAffineTransformMakeScale(scale,scale)];
    // UIImageに変換
    UIImage *newImg = [self uiImageFromCIImage:ciImage];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        completion(newImg);
    });
}

+ (void)centerCroppingImageWithImage:(UIImage*)img atSize:(CGSize)size completion:(void(^)(UIImage*))completion
{    
    CIImage *ciImage = [[CIImage alloc] initWithImage:img];
    /* 画像のサイズ */
    CGSize imgSize = CGSizeMake(img.size.width * img.scale,
                                img.size.height * img.scale);
    /* トリミングするサイズ */
    CGSize croppingSize = CGSizeMake(size.width * [UIScreen mainScreen].scale,
                                     size.height * [UIScreen mainScreen].scale);
    /* 中央でトリミング */
    CIImage *filteredImage = [ciImage imageByCroppingToRect:CGRectMake(imgSize.width/2.f - croppingSize.width/2.f,
                                                                       imgSize.height/2.f - croppingSize.height/2.f,
                                                                       croppingSize.width,
                                                                       croppingSize.height)];    
    /* UIImageに変換する */
    UIImage *newImg = [self uiImageFromCIImage:ciImage];
   
    dispatch_async(dispatch_get_main_queue(), ^{
        completion(newImg);
    });
}

+ (UIImage*)uiImageFromCIImage:(CIImage*)ciImage
{
    CIContext *ciContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @NO }];
    CGImageRef imgRef = [ciContext createCGImage:ciImage fromRect:[ciImage extent]];
    UIImage *newImg  = [UIImage imageWithCGImage:imgRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
    CGImageRelease(imgRef);
    return newImg;
    
    /* iOS6.0以降だと以下が使用可能 */
//  [[UIImage alloc] initWithCIImage:ciImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
}

@end
```

## 使用例

リサイズ

```objectivec:
[UIImage resizeAspectFitImageWithImage:img atSize:200.f completion:^(UIImage *resultImg){
    self.imageView.image = resultImg;
    [self.imageView sizeToFit];
}];
```

トリミング

```objectivec:
[UIImage centerCroppingImageWithImage:img atSize:CGSizeMake(300.f, 300.f) completion:^(UIImage *resultImg){
    self.imageView.image = resultImg;
    [self.imageView sizeToFit];
}];
```

リサイズ処理をバックグラウンドで実行

```objectivec:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [UIImage resizeAspectFitImageWithImage:img atSize:200.f completion:^(UIImage *resultImg){
        self.imageView.image = resultImg;
        [self.imageView sizeToFit];
    }];
});
```