UIImageresize无法正常工作

所以我一直在试图弄清楚我现在做错了一段时间,而我无法弄清楚。 我试图完成的是这样的:

  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 

正如你在下面的图片中看到的,它最终变形了。
形式与按钮

至于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]; } 

在这一点上,我不知道如何让这个图像显示没有扭曲。 尽pipe系统说这个图像确实是一个方形的,但是它似乎将它错误地显示出来并显示错误。

由于其他原因,我放弃了那个vocaro.com解决scheme(当使用非典型图像格式,例如CMYK时,解决scheme会崩溃)。

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

顺便说一下,这会自动应用设备的主屏幕的比例(例如,在Retina设备上的60×60点的UIButtonbutton,这将应用2x(或3x)的比例,即120×120或180×180图像)。

的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