在 iOS 8.4 中裁剪 UIImage 并发症 [重复]

Posted

技术标签:

【中文标题】在 iOS 8.4 中裁剪 UIImage 并发症 [重复]【英文标题】:Cropping UIImage Complications in iOS 8.4 [duplicate] 【发布时间】:2015-07-07 01:28:08 【问题描述】:

我目前正在用我的 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 方法如下:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
   
    picker.allowsEditing = YES;

    UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];

    CGRect cropRect = CGRectMake(0, 0, 2448, 3264);

    UIImage *croppedImage = [img crop:cropRect];

    imageToPass = croppedImage;

    NSLog(@"Here's imageToPass: %@", imageToPass);
    NSLog(@"and here's imageToPass' width: %f", imageToPass.size.width);
    NSLog(@"and here's imageToPass' height: %f", imageToPass.size.height);
    NSLog(@"and here's imageToPass' scale: %f", imageToPass.scale);

    UINavigationController *postControl = [self.storyboard instantiateViewControllerWithIdentifier:@"postControl"];
    RGPostViewController *postView = (RGPostViewController *)postControl.topViewController;

    [postView storeImage:imageToPass];

    [self.presentedViewController presentViewController:postControl animated:NO completion:nil];

我的问题是,当我打印 imageToPass 变量的宽度和高度时,我发现该值以点为单位列出。我的控制台打印如下:

我需要返回一个裁剪为 320x320 大小的图像。使用我的代码CGRect cropRect = CGRectMake(0, 0, 2448, 3264); 我采用照片的原始尺寸,默认情况下 UIImagePickerController 是,我假设,320x520 或类似的东西。使用点值我可以看到 2448 是点宽,3264 是点高度。来自谷歌,

iPhone 5 的显示分辨率为 1136 x 640 像素。新触摸屏的对角线尺寸为 4 英寸,纵横比为 16:9,并带有 326 ppi(每英寸像素)的 Retina 显示屏。

我不知道在这里做什么。 2448points/640px = 3.825 的数学是否告诉我在 326ppi 屏幕上每个像素有 3.825 个点?

PS 请记住,我正在尝试在 UIImagePickerControllerOriginalImage 中间抓取 320x320 图片,这意味着切割一些顶部像素数和一些底部像素数,以我假设的点数确定。

编辑

这是上面第四行代码中crop:方法的代码:

#import "UIImage+Crop.h"

@implementation UIImage (Crop)

- (UIImage *)crop:(CGRect)rect 

    rect = CGRectMake(rect.origin.x*self.scale,
                      rect.origin.y*self.scale,
                      rect.size.width*self.scale,
                      rect.size.height*self.scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
    UIImage *result = [UIImage imageWithCGImage:imageRef
                                          scale:self.scale
                                    orientation:self.imageOrientation];
    CGImageRelease(imageRef);
    return result;


@end

我发现如果我将CGRect cropRect 设置为CGRect cropRect = CGRectMake(264, 0, 2448, 3000); //3264,它实际上会从图像的顶部和底部移除264 个点。我了解 iPhone 5s 的屏幕分辨率为 326ppi(每英寸像素),我该如何使用它来成功移除需要移除的像素数量。

【问题讨论】:

这应该比现在简单很多 你的意思是你想要一个 320x320 的正方形点从你的图像中心,还是你的意思是你想裁剪你的图像,使它成为正方形? 我想将我的图像裁剪成完美的正方形。我什至不确定图像为 320x320 意味着什么。因为它说屏幕是 640x1136,将它们除以 2 得到 320x568,这实际上是 Storyboard 文件中的视图。完全对所有这些测量感到困惑,但我只需要切断 UIImagePickerController 的顶部和底部即可“调整”图像。 在这种情况下,我会编辑您的问题并删除所有对 320x320 的引用,因为人们正试图使用​​该信息来回答。而且ppi也是一条红鲱鱼!我只想说“我如何裁剪 UIImage 以使其成为正方形”,然后看看你会得到什么答案。 这可能会有所帮助:***.com/questions/14203951/… 【参考方案1】:

由于屏幕的属性scale,您无需了解转换点/像素/视网膜/非/等。不过,您确实需要使用核心图形来进行实际裁剪。下面是它的样子:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info    
    picker.allowsEditing = YES;

    UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];

    // you want to make your rect in the center of your image, not at [0,0]
    CGFloat cropSize = 320;
    CGRect cropRect = CGRectMake(img.center.x - (cropSize / 2), img.center.y - (cropSize / 2), cropSize, cropSize);

    // Make a new CGImageRef with the current graphics context, then use that to make the cropped UIImage. Make sure to release that image ref!
    CGImageRef imageRef = CGImageCreateWithImageInRect([img CGImage], cropRect);
    croppedImage = [UIImage imageWithCGImage: imageRef];
    CGImageRelease(imageRef);

    // Adjust the image for scale - this is how you handle retina/orientation.
    imageToPass = [UIImage imageWithCGImage:imageRef 
                                      scale:self.scale 
                                orientation:self.imageOrientation];

    UINavigationController *postControl = [self.storyboard instantiateViewControllerWithIdentifier:@"postControl"];
    RGPostViewController *postView = (RGPostViewController *)postControl.topViewController;

    [postView storeImage:imageToPass];

    [self.presentedViewController presentViewController:postControl animated:NO completion:nil];

【讨论】:

是的,这是完全错误的,哈哈。 怎么样?我误解了你想做什么吗?我发布的答案将为您提供 320x320 的中心裁剪。 嗯,首先,UIImage 没有这样的属性“center.x”。如果您将其更改为img.size.width/2,它仍然无法正常工作。与center.y.. 相同。不存在。此外,当使用scaleorientation 设置imageToPass 时,您不能使用self.scale 和self.imageOrientation,因为'self' 不是UIImage。因此,必须将其更改为croppedImage.scale 等或img.scale 等。哦!并且CGRect cropRect 不需要cropSize = 320 的宽度和高度,因为它是以点而不是320 为单位测量的。正如我所说,originalImage 是 CGRectMake(0, 0, 2448, 3264); 你是对的,请原谅我的错误输入。改编自我最近开发的裁剪控制器,并且已经为比例和图像方向定义了属性。可以通过以下方式确定规模:[UIScreen mainScreen].scale 其实没有...scaleimageOrientation都是UIImage的属性...所以只需将self.scale改为img.scale即可。抱歉打错了。我也不确定您为什么要对图像大小进行硬编码。你所有的图像永远都是一样的吗?裁剪的像素大小是您定义的大小 (cropRect) 和比例的组合。

以上是关于在 iOS 8.4 中裁剪 UIImage 并发症 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

像IOS 5一样裁剪UIImage时如何制作视图效果?

从照片图像中选择和裁剪人脸图像(ios)

iOS高效裁剪图片圆角算法

iOS - 将图像裁剪为检测到的面部的问题

在裁剪之前调整 UIImage 或 CIImage 的大小会拉伸图像吗?

UIImage 在裁剪后被旋转