将图像裁剪为 CGRect 始终从 x:0 和 y:0 开始

Posted

技术标签:

【中文标题】将图像裁剪为 CGRect 始终从 x:0 和 y:0 开始【英文标题】:Crop Image into CGRect always starts from x:0 and y:0 【发布时间】:2018-09-26 08:41:47 【问题描述】:

我有这个 sn-p 代码,它在我这边运行良好,它根据我的可拖动 UIImageView(称为 cropOverlay)的大小裁剪图像:

func cropImage() 
        let rect = CGRect(x: cropOverlay.frame.origin.x, y: cropOverlay.frame.origin.y, width: cropOverlay.frame.size.width, height: cropOverlay.frame.size.height)
        UIGraphicsBeginImageContextWithOptions(rect.size, true, 0.0)
        originalImgView.layer.render(in: UIGraphicsGetCurrentContext()!)
        imageToEdit = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        originalImgView.image = imageToEdit
        resizeImageViewToImageSize(originalImgView)
        cropOverlay.frame = originalImgView.frame

        print("cropOverlay: \(cropOverlay.frame)")
        print("originalImgView: \(originalImgView.frame)")
        print("imageToEdit: \(imageToEdit.size.width) - \(imageToEdit.size.height)\n")
    

这是我在 XCode 控制台中得到的:

cropOverlay: (139.25111636459152, 154.66666666666663, 135.49776727081695, 426.66666666666674)
originalImgView: (139.25111636459152, 154.66666666666663, 135.49776727081695, 426.66666666666674)
imageToEdit: 134.33333333333334 - 423.0

所以,我的控制台日志显示了我的cropOverlay imageView 的正确 X 和 Y 位置,以及我的 originalImageView 帧数据。但问题是,我将cropOverlay imageView 移动到哪里并不重要,即使控制台说它在 X:139 和 Y:154,我得到的图像结果从 X.0 和 Y:0 开始.查看这些屏幕截图以更好地了解我的问题:

之前

应用cropImage()函数后

PS:我的resizeImageViewToImageSize(originalImgView) 函数只是根据其 UIImage 大小调整我的originalImageView 框架的大小并将其在屏幕上居中。 如您所见,裁剪后的图像大小是正确的,但它是从我的原始图像的 X 和 Y = 0 开始的。

我在代码中做错了什么?

谢谢!

更新: 如下所示,我已经像这样编辑了我的cropImage() 函数:

func cropImage() 

        let cutImageRef: CGImage = (originalImgView.image!.cgImage?.cropping(to: cropOverlay.frame))!
        imageToEdit = UIImage(cgImage: cutImageRef)

        originalImgView.image = imageToEdit
        resizeImageViewToImageSize(originalImgView)
        cropOverlay.frame = originalImgView.frame

但这是我得到的结果:

【问题讨论】:

【参考方案1】:

CGImage 可以使用 Apple 方法

https://developer.apple.com/documentation/coregraphics/cgimage/1454683-cropping

裁剪(到:)

使用包含在子区域中的数据创建位图图像 一个现有的位图图像。

例如:

let cutImageRef: CGImage = originalImgView.image.cgImage?.cropping(to: cropOverlay.frame)
let croppedImage: UIImage = UIImage(cgImage: cutImageRef)

更新:

你也应该使用比例尺,因为你 imageView 的大小与图像的大小不同

if let image = imageView.image 
  let wScale = (image.size.width / imageView.frame.width) * UIScreen.main.scale
  let hScale = (image.size.height / imageView.frame.height) * UIScreen.main.scale
  ...
  // Create cropping area using scales

【讨论】:

抱歉,它不起作用,它会裁剪我的 UIImage 的一小部分,使其变大并再次从 x,y = 0 开始。我什至试过Apple的代码,它是错误的:( 赞成这个,这绝对是正确的做法。如果您尝试过但没有成功,请对您的问题发布更新,显示您使用的代码,我相信有人可以提供进一步帮助。 好的,@PeteMorris,我现在要发布更新,谢谢。 由于某种原因,该代码使裁剪后的图像大了 2 倍(至少在我看来是这样) PS:我猜问题出在 UIImage 尺寸上,如果这样的尺寸像 1500x2000 这样大,那么裁剪结果就是这样图像的一小部分:(【参考方案2】:
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)

第一个参数的类型是 CGSize,而不是 CGRect。你可以试试这个:

CGImageRef sourceImageRef = [originalImageView.image CGImage];
CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);

【讨论】:

那是 Objective-C,我的问题需要 Swift 代码回答 :) 我可以将你的 Obj-.C 代码翻译成 Swift,如下所示: let cutImageRef: CGImage = (imageToEdit.cgImage?.cropping(to:cropOverlay.frame))! letcroppedImg = UIImage(cgImage: cutImageRef) 但它还不能正常工作...

以上是关于将图像裁剪为 CGRect 始终从 x:0 和 y:0 开始的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Opencv 中使用 CgRect 裁剪图像。

裁剪 JPEG 图像而不重新采样

如何使用 CSS 居中和裁剪图像以始终以方形显示?

通过在 imageview 中绘制圆圈裁剪图像

裁剪图像包含在 4 边(非矩形)多边形中

从 Swift 中的自定义相机拍摄后裁剪图像