由于其他原因,我放弃了 vocaro.com 解决方案(该解决方案在与非典型图像格式(例如 CMYK)一起使用时会崩溃)。
无论如何,我现在使用imageByScalingAspectFillSize
以下UIImage
类别的方法来制作我的方形缩略图。
顺便说一句,这会自动应用设备主屏幕的比例(例如UIButton
,在 Retina 设备上是 60x60 点的按钮,这将应用 2x(或 3x)的比例,即 120x120 或 180x180 图像)。
UIImage+SimpleResize.h:
/* UIImage+SimpleResize.h
*
* Modified by Robert Ryan on 5/19/11.
*/
@import UIKit;
/** Image resizing category.
*
* Modified by Robert Ryan on 5/19/11.
*
* Inspired by http://ofcodeandmen.poltras.com/2008/10/30/undocumented-uiimage-resizing/
* but adjusted to support AspectFill and AspectFit modes.
*/
@interface UIImage (SimpleResize)
/** Resize the image to be the required size, stretching it as needed.
*
* @param size The new size of the image.
* @param contentMode The `UIViewContentMode` to be applied when resizing image.
* Either `UIViewContentModeScaleToFill`, `UIViewContentModeScaleAspectFill`, or
* `UIViewContentModeScaleAspectFit`.
*
* @return Return `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode;
/** Resize the image to be the required size, stretching it as needed.
*
* @param size The new size of the image.
* @param contentMode The `UIViewContentMode` to be applied when resizing image.
* Either `UIViewContentModeScaleToFill`, `UIViewContentModeScaleAspectFill`, or
* `UIViewContentModeScaleAspectFit`.
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
*
* @return Return `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode scale:(CGFloat)scale;
/** Crop the image to be the required size.
*
* @param bounds The bounds to which the new image should be cropped.
*
* @return Cropped `UIImage`.
*/
- (UIImage * _Nullable)imageByCroppingToBounds:(CGRect)bounds;
/** Crop the image to be the required size.
*
* @param bounds The bounds to which the new image should be cropped.
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
*
* @return Cropped `UIImage`.
*/
- (UIImage * _Nullable)imageByCroppingToBounds:(CGRect)bounds scale:(CGFloat)scale;
/** Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed.
*
* @param size The new size of the image.
*
* @return Return `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingAspectFillSize:(CGSize)size;
/** Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed.
*
* @param size The new size of the image.
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
*
* @return Return `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingAspectFillSize:(CGSize)size scale:(CGFloat)scale;
/** Resize the image to be the required size, stretching it as needed.
*
* @param size The new size of the image.
*
* @return Resized `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingToFillSize:(CGSize)size;
/** Resize the image to be the required size, stretching it as needed.
*
* @param size The new size of the image.
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
*
* @return Resized `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingToFillSize:(CGSize)size scale:(CGFloat)scale;
/** Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place.
*
* @param size The new size of the image.
*
* @return Return `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingAspectFitSize:(CGSize)size;
/** Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place.
*
* @param size The new size of the image.
* @param scale The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
*
* @return Return `UIImage` of resized image.
*/
- (UIImage * _Nullable)imageByScalingAspectFitSize:(CGSize)size scale:(CGFloat)scale;
@end
UIImage+SimpleResize.m:
// UIImage+SimpleResize.m
//
// Created by Robert Ryan on 5/19/11.
#import "UIImage+SimpleResize.h"
@implementation UIImage (SimpleResize)
- (UIImage *)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode {
return [self imageByScalingToSize:size contentMode:contentMode scale:0];
}
- (UIImage *)imageByScalingToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode scale:(CGFloat)scale {
if (contentMode == UIViewContentModeScaleToFill) {
return [self imageByScalingToFillSize:size];
}
else if ((contentMode == UIViewContentModeScaleAspectFill) ||
(contentMode == UIViewContentModeScaleAspectFit)) {
CGFloat horizontalRatio = self.size.width / size.width;
CGFloat verticalRatio = self.size.height / size.height;
CGFloat ratio;
if (contentMode == UIViewContentModeScaleAspectFill)
ratio = MIN(horizontalRatio, verticalRatio);
else
ratio = MAX(horizontalRatio, verticalRatio);
CGSize sizeForAspectScale = CGSizeMake(self.size.width / ratio, self.size.height / ratio);
UIImage *image = [self imageByScalingToFillSize:sizeForAspectScale scale:scale];
// if we're doing aspect fill, then the image still needs to be cropped
if (contentMode == UIViewContentModeScaleAspectFill) {
CGRect subRect = CGRectMake(floor((sizeForAspectScale.width - size.width) / 2.0),
floor((sizeForAspectScale.height - size.height) / 2.0),
size.width,
size.height);
image = [image imageByCroppingToBounds:subRect];
}
return image;
}
return nil;
}
- (UIImage *)imageByCroppingToBounds:(CGRect)bounds {
return [self imageByCroppingToBounds:bounds scale:0];
}
- (UIImage *)imageByCroppingToBounds:(CGRect)bounds scale:(CGFloat)scale {
if (scale == 0) {
scale = [[UIScreen mainScreen] scale];
}
CGRect rect = CGRectMake(bounds.origin.x * scale, bounds.origin.y * scale, bounds.size.width * scale, bounds.size.height * scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef scale:scale orientation:self.imageOrientation];
CGImageRelease(imageRef);
return croppedImage;
}
- (UIImage *)imageByScalingToFillSize:(CGSize)size {
return [self imageByScalingToFillSize:size scale:0];
}
- (UIImage *)imageByScalingToFillSize:(CGSize)size scale:(CGFloat)scale {
UIGraphicsBeginImageContextWithOptions(size, false, scale);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (UIImage *)imageByScalingAspectFillSize:(CGSize)size {
return [self imageByScalingAspectFillSize:size scale:0];
}
- (UIImage *)imageByScalingAspectFillSize:(CGSize)size scale:(CGFloat)scale {
return [self imageByScalingToSize:size contentMode:UIViewContentModeScaleAspectFill scale:scale];
}
- (UIImage *)imageByScalingAspectFitSize:(CGSize)size {
return [self imageByScalingAspectFitSize:size scale:0];
}
- (UIImage *)imageByScalingAspectFitSize:(CGSize)size scale:(CGFloat)scale {
return [self imageByScalingToSize:size contentMode:UIViewContentModeScaleAspectFit scale:scale];
}
@end