【问题标题】:Crop image to a square according to the size of a UIView/CGRect根据 UIView/CGRect 的大小将图像裁剪为正方形
【发布时间】:2014-01-27 11:58:50
【问题描述】:

我有一个 AVCaptureSession 的实现,我的目标是让用户拍照并只保存红色方形边框内的部分图像,如下所示:

AVCaptureSession 的previewLayer(相机)从(0,0)(左上角)到我的相机控制栏底部(包含快门的视图上方的栏)。我的导航栏和控制栏是半透明的,所以相机可以通过。

我使用[captureSession setSessionPreset:AVCaptureSessionPresetPhoto]; 来确保保存到相机胶卷的原始图像就像苹果的相机一样。

用户将可以纵向、左右横向拍摄照片,因此裁剪方法必须考虑到这一点。

到目前为止,我已经尝试使用以下代码裁剪原始图像:

DDLogVerbose(@"%@: Image crop rect: (%f, %f, %f, %f)", THIS_FILE, self.imageCropRect.origin.x, self.imageCropRect.origin.y, self.imageCropRect.size.width, self.imageCropRect.size.height);

// Create new image context (retina safe)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.imageCropRect.size.width, self.imageCropRect.size.width), NO, 0.0);

// Create rect for image
CGRect rect = self.imageCropRect;

// Draw the image into the rect
[self.captureManager.stillImage drawInRect:rect];

// Saving the image, ending image context
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();

但是,当我查看相机胶卷中裁剪后的图像时,它似乎只是挤压了原始图像,并没有像我想要的那样丢弃图像的顶部和底部。它还会在“裁剪”图像的顶部产生 53 像素的空白,这可能是因为我的 CGRect 的 y 位置。

这是我对CGRect 的日志输出:

 Image crop rect: (0.000000, 53.000000, 320.000000, 322.000000)

这也描述了superview中红色边框的view的frame。

我忽略了一些重要的事情吗?

附:原始图像尺寸(使用相机在纵向模式下拍摄)为:

Original image size: (2448.000000, 3264.000000)

【问题讨论】:

    标签: ios uiimage crop image-resizing cgrect


    【解决方案1】:

    斯威夫特 3:

    let imageRef:CGImage = uncroppedImage.cgImage!.cropping(to: bounds)!
    let croppedImage:UIImage = UIImage(cgImage: imageRef)
    

    【讨论】:

    • 当我这样做时,它会将图像逆时针旋转 90 度。你知道如何解决旋转问题吗?
    • 为了防止旋转使用: letcroppedImage = UIImage(cgImage: imageRef, scale: UIScreen.main.scale,orientation: .right)
    【解决方案2】:

    不要忘记添加比例参数,否则你会得到低分辨率的图像

    CGImageRef imageRef = CGImageCreateWithImageInRect([uncroppedImage CGImage], CGRectMake(0, 0, 30, 120));
    [imageView setImage:[UIImage imageWithCGImage:imageRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp]];
    CGImageRelease(imageRef);
    

    【讨论】:

      【解决方案3】:

      您可以使用CGImageCreateWithImageInRect 裁剪图像:

      CGImageRef imageRef = CGImageCreateWithImageInRect([uncroppedImage CGImage], bounds);
      UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
      CGImageRelease(imageRef);
      

      【讨论】:

      • 我已经编辑了你的答案。因为原始图像大小可能与我们在屏幕上显示的图像不同。 :)
      • @Mani 谢谢。实际上,我并不是要在我的回答中建议一张图像与另一张图像,而是要展示一个通用的裁剪程序。 (它实际上改编自 UIImage 类别,显然只是引用了 self 而不是任何特定的图像)。我已经更改了我的变量名,以避免未来的读者跳到任何这样的结论。是否拍摄快照并对其进行裁剪,或者是否在裁剪之前返回原始图像(相应地调整裁剪CGRect)是应用程序要求的功能。
      • 非常重要的注意事项!无法真正解释,但只能假设 Core Graphics 处理反转的轴,x 代表 y,y 代表 x。至少对我来说,在将图像转换为核心图形图像时,它的宽度和高度是相反的。所以当你裁剪某些东西时要小心,特别是如果你想从特定的 x 或 y 而不是从 (0,0) 裁剪。
      猜你喜欢
      • 1970-01-01
      • 2012-04-23
      • 2013-12-30
      • 2020-02-06
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      相关资源
      最近更新 更多