CoreImageを使用したリサイズと画像の中央からのトリミングです。
実装
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];
}];
});