UIImage调整大小无法正常工作

问题描述:

所以我一直在试图弄清楚我现在做错了一段时间,我无法弄清楚。我试图做到的是:UIImage调整大小无法正常工作

  1. ,要考虑与UIImagePickerController
  2. 照片承担由此产生的照片和剪切掉顶部和底部,使其成为一个正方形(类似于Instagram的)
  3. 显示内UIButton

出于某种原因形象,每次我把它结束了UIButton内扭曲照片并就好像裁剪没有正常工作时出现。这就是我所做的。内didFinishPickingMediaWithInfo方法,我有以下代码:

- (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的头文件中定义。日志输出结果如下:

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 

正如您在下面的图片中看到的,它最终会失真。
form with button

对于resizeAndRotate方法,那就是:

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

在这一点上我不知道如何得到这个图像显示不失真。尽管系统说图像确实是方形的,但它似乎将其错误地裁剪并显示错误。

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

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

顺便说一句,这会自动应用设备主屏幕的比例(例如UIButton按钮在Retina设备上为60x60点,这将应用2倍(或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 
+2

谢谢。经过数小时的沮丧和在线搜索尝试近20个建议的解决方案,这是唯一的解决方案已经工作。非常感谢。 – thephatp

+1

是。为我节省了几个小时的工作。我很欣赏这个类别! – kevinl