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

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

问题描述

所以我一直在想弄清楚我做错了一会儿,我现在不知道。我想要完成的是:


  1. 使用UIImagePickerController拍摄照片


  2. 在UIButton中显示该图片

由于某些原因,每次我拍照,它最终在UIButton中扭曲,看起来好像裁剪不能正常工作。这是我做的。在didFinishPickingMediaWithInfo方法中,我有以下代码:

   - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: )info 
{
//将图像复制到userImage变量
[picker dismissModalViewControllerAnimated:YES];
userImage = nil;

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

//使用图像更新图像形式字段并在控制器中设置图像
NSLog(@按钮大小为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]按钮大小为height:60.000000,width:60.000000
pre>

如下图所示,它最终会扭曲。



对于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尺寸;
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使用)。



无论如何,我现在使用 UIImage imageByScalingAspectFillSize $ c>类别,使我的正方形缩略图。



顺便说一下,在Retina设备上,如果您为 UIButton 按钮创建一个图像60 x 60点,您可能需要使用120 x 120像素的图片。

  // UIImage + SimpleResize.m 
//
//由Robert Ryan于5/19/11创建。

#importUIImage + SimpleResize.h

@implementation UIImage(SimpleResize)

- (UIImage *)imageByScalingToSize:(CGSize)newSize contentMode:(UIViewContentMode)contentMode
{
if(contentMode == UIViewContentModeScaleToFill)
{
return [self imageByScalingToFillSize:newSize];
}
else if((contentMode == UIViewContentModeScaleAspectFill)||
(contentMode == UIViewContentModeScaleAspectFit))
{
CGFloat horizo​​ntalRatio = self.size.width / newSize 。宽度;
CGFloat verticalRatio = self.size.height / newSize.height;
CGFloat比率;

if(contentMode == UIViewContentModeScaleAspectFill)
ratio = MIN(horizo​​ntalRatio,verticalRatio);
else
ratio = MAX(horizo​​ntalRatio,verticalRatio);

CGSize sizeForAspectScale = CGSizeMake(self.size.width / ratio,self.size.height / ratio);

UIImage * image = [self imageByScalingToFillSize:sizeForAspectScale];

//如果我们正在做方向填充,那么图像仍然需要裁剪

if(contentMode == UIViewContentModeScaleAspectFill)
{
CGRect subRect = CGRectMake(floor((sizeForAspectScale.width - newSize.width)/ 2.0),
floor((sizeForAspectScale.height - newSize.height)/ 2.0),
newSize.width,
newSize.height);
image = [image imageByCroppingToBounds:subRect];
}

return image;
}

return nil;
}

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds
{
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage],bounds);
UIImage * croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}

- (UIImage *)imageByScalingToFillSize:(CGSize)newSize
{
UIGraphicsBeginImageContext(newSize);
[self drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;
}

- (UIImage *)imageByScalingAspectFillSize:(CGSize)newSize
{
return [self imageByScalingToSize:newSize contentMode:UIViewContentModeScaleAspectFill];
}

- (UIImage *)imageByScalingAspectFitSize:(CGSize)newSize
{
return [self imageByScalingToSize:newSize contentMode:UIViewContentModeScaleAspectFit];
}

@end

/ p>

  // UIImage + SimpleResize.h 
//
//由Robert Ryan创建于5/19 / 11。

#import< Foundation / Foundation.h>

/ **图像调整大小类别。
*
*由Robert Ryan于5/19/11修改。
*
*受http://ofcodeandmen.poltras.com/2008/10/30/undocumented-uiimage-resizing/
*启发,但调整为支持AspectFill和AspectFit模式。
* /

@interface UIImage(SimpleResize)

/ **将图像大小调整为所需大小,根据需要进行伸展。
*
* @param newSize图像的新大小。
* @param contentMode调整图像大小时应用的`UIViewContentMode`。
*`UIViewContentModeScaleToFill`,`UIViewContentModeScaleAspectFill`或
*`UIViewContentModeScaleAspectFit`。
*
* @return返回`UIImage`调整大小的图像。
* /

- (UIImage *)imageByScalingToSize:(CGSize)newSize contentMode:(UIViewContentMode)contentMode;

/ **将图像裁剪为所需的大小。
*
* @param bounds应该裁剪新图像的边界。
*
* @return裁剪`UIImage`。
* /

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds;

/ **将图像调整为所需的大小,根据需要进行伸展。
*
* @param newSize图像的新大小。
*
* @return调整大小的图像大小的`UIImage`。
* /

- (UIImage *)imageByScalingToFillSize:(CGSize)newSize;

/ **调整图像大小以填充指定尺寸的矩形,保留宽高比,如果需要,修剪。
*
* @param newSize图像的新大小。
*
* @return返回`UIImage`调整大小的图像。
* /

- (UIImage *)imageByScalingAspectFillSize:(CGSize)newSize;

/ **调整图像大小以适合所需的大小,保留宽高比,不进行裁剪。
*
* @param newSize图像的新大小。
*
* @return返回`UIImage`调整大小的图像。
* /

- (UIImage *)imageByScalingAspectFitSize:(CGSize)newSize;

@end


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

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

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.

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.

解决方案

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

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

By the way, on Retina devices, if you're creating an image for a UIButton button that is is 60 x 60 points, you may want to use a 120 x 120 pixels image.

//  UIImage+SimpleResize.m
//
//  Created by Robert Ryan on 5/19/11.

#import "UIImage+SimpleResize.h"

@implementation UIImage (SimpleResize)

- (UIImage*)imageByScalingToSize:(CGSize)newSize contentMode:(UIViewContentMode)contentMode
{
    if (contentMode == UIViewContentModeScaleToFill)
    {
        return [self imageByScalingToFillSize:newSize];
    }
    else if ((contentMode == UIViewContentModeScaleAspectFill) ||
             (contentMode == UIViewContentModeScaleAspectFit))
    {
        CGFloat horizontalRatio   = self.size.width  / newSize.width;
        CGFloat verticalRatio     = self.size.height / newSize.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];

        // if we're doing aspect fill, then the image still needs to be cropped

        if (contentMode == UIViewContentModeScaleAspectFill)
        {
            CGRect  subRect = CGRectMake(floor((sizeForAspectScale.width - newSize.width) / 2.0),
                                         floor((sizeForAspectScale.height - newSize.height) / 2.0),
                                         newSize.width,
                                         newSize.height);
            image = [image imageByCroppingToBounds:subRect];
        }

        return image;
    }

    return nil;
}

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds
{
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return croppedImage;
}

- (UIImage*)imageByScalingToFillSize:(CGSize)newSize
{
    UIGraphicsBeginImageContext(newSize);
    [self drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

- (UIImage*)imageByScalingAspectFillSize:(CGSize)newSize
{
    return [self imageByScalingToSize:newSize contentMode:UIViewContentModeScaleAspectFill];
}

- (UIImage*)imageByScalingAspectFitSize:(CGSize)newSize
{
    return [self imageByScalingToSize:newSize contentMode:UIViewContentModeScaleAspectFit];
}

@end

And, the header:

//  UIImage+SimpleResize.h
//
//  Created by Robert Ryan on 5/19/11.

#import <Foundation/Foundation.h>

/** 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 newSize      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*)imageByScalingToSize:(CGSize)newSize contentMode:(UIViewContentMode)contentMode;

/** Crop the image to be the required size.
 *
 * @param bounds       The bounds to which the new image should be cropped.
 *
 * @return             Cropped `UIImage`.
 */

- (UIImage *)imageByCroppingToBounds:(CGRect)bounds;

/** Resize the image to be the required size, stretching it as needed.
 *
 * @param newSize The new size of the image.
 *
 * @return        Resized `UIImage` of resized image.
 */

- (UIImage*)imageByScalingToFillSize:(CGSize)newSize;

/** Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed.
 *
 * @param newSize The new size of the image.
 *
 * @return        Return `UIImage` of resized image.
 */

- (UIImage*)imageByScalingAspectFillSize:(CGSize)newSize;

/** Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place.
 *
 * @param newSize The new size of the image.
 *
 * @return        Return `UIImage` of resized image.
 */

- (UIImage*)imageByScalingAspectFitSize:(CGSize)newSize;

@end

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

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