UIImage 调整大小无法正常工作 [英] UIImage resizing not working properly

查看:21
本文介绍了UIImage 调整大小无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以一段时间以来我一直试图弄清楚我做错了什么,但我无法弄清楚.我想要完成的是:

So I've been trying to figure out what I'm doing wrong for a while now and I can't figure it out. What I'm trying to accomplish is this:

  1. 使用 UIImagePickerController
  2. 拍照
  3. 拍摄生成的照片并剪掉顶部和底部,使其变成正方形(类似于 Instagram)
  4. UIButton
  5. 中显示该图像
  1. Take a photo with UIImagePickerController
  2. Take the resulting photo and crop off the top and bottom so it becomes a square (similar to Instagram)
  3. Display that image within a UIButton

出于某种原因,每次我拍摄照片时,它都会在 UIButton 内变形,看起来好像裁剪没有正常工作.这就是我所做的.在 didFinishPickingMediaWithInfo 方法中,我有以下代码:

For some reason, every time I take the photo it ends up distorted within the UIButton and it appears as though the cropping didn't work properly. Here's what I do. Within the didFinishPickingMediaWithInfo method I have the following code:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    //Copy the image to the userImage variable
    [picker dismissModalViewControllerAnimated:YES];
    userImage = nil;

    //Rotate & resize image
    userImage = [self resizeAndRotatePhoto:(UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage]];
    NSLog(@"Userimage size, width: %f , height: %f", userImage.size.width , userImage.size.height);

    //Update the image form field with the image and set the image in the controller
    NSLog(@"Button size is height: %f , width: %f" , userImageAvatarButton.frame.size.height , userImageAvatarButton.frame.size.width);
   [userImageAvatarButton.layer setMasksToBounds:YES];
   [userImageAvatarButton.layer setCornerRadius:3.0];
   [userImageAvatarButton setImage:userImage forState:UIControlStateNormal];
}

我将暂时包括 resizeAndRotatePhoto 方法,但结果如下.另外,在上面的代码中,@property (strong) (UIImage *)userImage; 是在ViewController 的头文件中定义的.日志输出还导致:

I'll include the resizeAndRotatePhoto method momentarily but the result is below. Also, in the code above, @property (strong) (UIImage *)userImage; is defined in the ViewController's header file. The log output also results in:

2012-05-07 17:38:07.995 NewApp[10666:707] Userimage size, width: 1936.000000 , height: 1936.000000
2012-05-07 17:38:08.000 NewApp[10666:707] Button size is height: 60.000000 , width: 60.000000

如下图所示,它最终变形了.

As you see in the image below, it ends up distorted.

至于 resizeAndRotate 方法,这里是:

As for the resizeAndRotate method, here it is:

- (UIImage *)resizeAndRotatePhoto:(UIImage *)source
{
if( source.imageOrientation == UIImageOrientationRight )
{
    source = [self rotateImage:source byDegrees:90];
}
if( userImage.imageOrientation == UIImageOrientationLeft)
{
    source = [self rotateImage:source byDegrees:-90];
}

CGFloat x,y;
CGFloat size;
if( source.size.width > source.size.height ){
    size = source.size.height;
    x = (source.size.width - source.size.height)/2;
    y = 0;
}
else {
    size = source.size.width;
    x = 0;
    y = (source.size.height - source.size.width)/2;
}


CGImageRef imageRef = CGImageCreateWithImageInRect([source CGImage], CGRectMake(x,y,size,size) );
return [UIImage imageWithCGImage:imageRef];
}

此时我不知道如何让这张图片不失真地显示.尽管系统说图像确实是一个正方形,但它似乎裁剪错误并显示错误.

At this point I have no idea how to get this image to show up undistorted. It appears to be cropping it wrong and displaying it wrong despite the system saying that the image is indeed a square.

推荐答案

我出于其他原因放弃了 vocaro.com 解决方案(该解决方案在使用非典型图像格式时会崩溃,例如 CMYK).

I abandoned that vocaro.com solution for other reasons (that solution would crash when used with atypical image formats, e.g. CMYK).

无论如何,我现在使用以下 UIImage 类别的 imageByScalingAspectFillSize 方法来制作我的方形缩略图.

Anyway, I now use the imageByScalingAspectFillSize method of the following UIImage category to make my square thumbnails.

顺便说一下,这会自动应用设备主屏幕的比例(例如 UIButton 按钮,在 Retina 设备上是 60x60 点,这将应用 2x(或 3x)的比例),即 120x120 或 180x180 图像).

By the way, this automatically applies the scale of the main screen of the device (e.g. UIButton button that is is 60x60 points on a Retina device, this will apply that scale of 2x (or 3x), i.e. a 120x120 or 180x180 image).

UIImage+SimpleResize.h:

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:

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

这篇关于UIImage 调整大小无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆