LoginSignup
50

More than 5 years have passed since last update.

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

Posted at

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

ss1

ss2

実装

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

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
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

使用例

リサイズ

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

トリミング

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

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

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];
    }];
});

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50