iOS UIImage等比缩放、转到横屏的图片到垂直模式、重制大小resize

雍马鲁
2023-12-01

UIImage等比缩放

分类方法

@implementation UIImage (Cat)

// 计算等比缩放图片的size
- (CGSize)equalRatioComputeImageWithTargetWidth:(CGFloat)targetWidth targetHeight:(CGFloat)targetHeight {
    CGFloat originalWidth = self.size.width;
    CGFloat originalHeight = self.size.height;
    
    CGFloat widthFactor = targetWidth / originalWidth;
    CGFloat heightFactor = targetHeight / originalHeight;

    CGFloat scaleFactor = 0;
    if (widthFactor > heightFactor) {
        scaleFactor = widthFactor;
    } else {
        scaleFactor = heightFactor;
    }

    CGFloat scaledWidth = originalWidth * scaleFactor;
    CGFloat scaledHeight = originalHeight * scaleFactor;

    return CGSizeMake(scaledWidth, scaledHeight);
}

// 计算等比缩放图片到屏幕大小的size
- (CGSize)equalRatioComputeImageToScreenSize {
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    return [self equalRatioComputeImageWithTargetWidth:screenSize.width targetHeight:screenSize.height];
}

}

调用:

// 计算图片等比缩放到屏幕大小的size
CGSize imageMaxSize = [portraitImage equalRatioComputeImageToScreenSize];

转到横屏的图片到垂直模式

@implementation YDImageEXIFTool

// 根据图片的NSData获取图片的EXIF信息
+ (NSDictionary *)getExifInfoWithImageData:(NSData *)imageData {
    CGImageSourceRef cImageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
    NSDictionary *dict =  (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(cImageSource, 0, NULL));
    NSDictionary *dictInfo = [NSDictionary dictionaryWithDictionary:dict];
    return dictInfo;
}

// 根据图片本地URL获取图片的EXIF信息
+ (NSDictionary *)getExifInfoWithImageURL:(NSURL *)url {
    CGImageSourceRef cImageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);
    NSDictionary *dict =  (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(cImageSource, 0, NULL));
    NSDictionary *dictInfo = [NSDictionary dictionaryWithDictionary:dict];
    return dictInfo;
}

// 将图片以JPEG格式写入到本地沙盒的临时文件夹里,并返回本地图片的路径
+ (NSString *)writeJPEGImageToLocalTemporaryFolder:(UIImage *)image {
    NSString *imgLocalPath = [NSString stringWithFormat:@"%@/%@.jpg", NSTemporaryDirectory(), [NSUUID UUID].UUIDString];
    NSData *jpgNSData = UIImageJPEGRepresentation(image, image.scale);
    [jpgNSData writeToFile:imgLocalPath atomically:YES];
    return imgLocalPath;
}

// 将UIImage图的方向调正,即竖屏可预览的模式
+ (UIImage *)convertImage:(UIImage *)image toRotation:(UIImageOrientation)orientation {
    if (image.imageOrientation == UIImageOrientationUp) return image;
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    /*
     Apple Doc: https://developer.apple.com/documentation/uikit/uiimage/1624092-drawinrect?language=objc
     解释:drawInRect方法会按照图片的系统默认坐标方向进行绘制,即修正图片不是portrait模式
     */
    [image drawInRect:(CGRect){0, 0, image.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

// 将UIImage图的方向调正,即默认竖屏可预览的模式
+ (UIImage *)convertImageToDefaultPortraitMode:(UIImage *)image {
    return [YDImageEXIFTool convertImage:image toRotation:UIImageOrientationUp];
}

@end

调用:

// 将图片转换成portrait模式,即垂直可预览模式
UIImage *portraitImage = [YDImageEXIFTool convertImageToDefaultPortraitMode:image];

重制大小resize

- (UIImage *)resizeImageToSize:(CGSize)size mode:(UIViewContentMode)mode {
    NSAssert([[NSThread currentThread] isMainThread], @"must be in main thread");
    UIImageView *view = [[UIImageView alloc] initWithImage:self];
    view.contentMode = mode;
    view.frame = CGRectMake(0, 0, size.width, size.height);
    view.backgroundColor = [UIColor clearColor];
    UIGraphicsBeginImageContextWithOptions(size, NO, 1);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:context];
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snapshotImage;
}

调用:

// 重制image的大小
UIImage *resizedImage = [portraitImage resizeImageToSize:imageMaxSize mode:UIViewContentModeScaleAspectFill];    

一个完整的例子

比如你在上传图片前,希望不管是横着拍的,还是竖着排的,还是全景图,还是超长大图,都可以这么转换

    // 将图片转换成portrait模式
    UIImage *portraitImage = [YDImageEXIFTool convertImageToDefaultPortraitMode:image];
    
    // 计算图片等比缩放到屏幕大小的size
    CGSize imageMaxSize = [portraitImage equalRatioComputeImageToScreenSize];
    
    // 重制image的大小
    UIImage *resizedImage = [portraitImage resizeImageToSize:imageMaxSize mode:UIViewContentModeScaleAspectFill];

最后将resizedImage发送到服务器
NSData *jpegData = UIImageJPEGRepresentation(resizedImage, 1.0);

 类似资料: