简体   繁体   English

裁剪UIImage无法获得预期的收成-快速吗?

[英]Cropping UIImage not yielding expected crop - swift?

I am trying to crop an image but the crop is not yielding the expected portion of the UIImage. 我正在尝试裁剪图像,但是裁剪无法产生UIImage的预期部分。 The images appear out of orientation and mirror-ed. 图像显示方向不正确并镜像。 It is very confusing. 这很令人困惑。

 @IBOutlet weak var imgPreViewOutlet: UIImageView!

 guard
        let cgImage = self.imgPreViewOutlet.image.cgImage else {return}


// NORMALISE COORDINATES
let topXn = TOP_LEFT.x/screenWidth
let topYn = TOP_LEFT.y/screenHeight
let widthn = (TOP_RIGHT.x - TOP_LEFT.x)/screenWidth
let heightn = (BOTTOM_RIGHT.y - TOP_RIGHT.y)/screenHeight


// DIMENSION OF CGIMAGE
let cgImgWidth = cgImage.width
let cgImgHeight = cgImage.height

let cropRect = CGRect.init(x: topXn * CGFloat.init(widthn) , y: topYn * CGFloat.init(heightn), width: widthn * CGFloat.init(cgImgWidth), height: heightn * CGFloat.init(cgImgHeight))

if let cgCropImged = cgImage.cropping(to: cropRect){

        print("cropRect: \(cropRect)")

        self.imgPreViewOutlet.image = UIImage.init(cgImage: cgCropImged)
    }

在此处输入图片说明

CROPPED: 裁剪:

在此处输入图片说明

Core graphics coordinates are from an origin point at the bottom left, UIKit coordinates are from top left. 核心图形坐标从左下角的原点开始,UIKit坐标从左上角开始。 I think you're confusing the two. 我认为您混淆了两者。

This might help: 这可能会有所帮助:

How to compensate the flipped coordinate system of core graphics for easy drawing? 如何补偿核心图形的翻转坐标系以便于绘制?

As requested, here's an example of using CIPerspectiveCorrection to crop your image. 根据要求,下面是一个使用CIPerspectiveCorrection裁剪图像的示例。 I downloaded and used Sketch to get the approximate values of the 4 CGPoints in your example image. 我下载并使用了Sketch来获取示例图像中4个CGPoints的近似值。

    let inputBottomLeft = CIVector(x: 38, y: 122)
    let inputTopLeft = CIVector(x: 68, y: 236)
    let inputTopRight = CIVector(x: 146, y: 231)
    let inputBottomRight = CIVector(x: 151, y: 96)

    let filter = CIFilter(name: "CIPerspectiveCorrection")
    filter?.setValue(inputTopLeft, forKey: "inputTopLeft")
    filter?.setValue(inputTopRight, forKey: "inputTopRight")
    filter?.setValue(inputBottomLeft, forKey: "inputBottomLeft")
    filter?.setValue(inputBottomRight, forKey: "inputBottomRight")

    filter?.setValue(ciOriginal, forKey: "inputImage")
    let ciOutput = filter?.outputImage

Please note a few things: 请注意以下几点:

  • The most important thing to never forget about CoreImage is that the origin of a CIImage is bottom left, not top left. 永远不要忘记CoreImage最重要的事情是,起源CIImage左下角 ,而不是左上角 You need to "flip" the Y axis point. 您需要“翻转” Y轴点。
  • A UIImage has a size, while a CIImage has an extent. UIImage具有大小,而CIImage具有范围。 These are the same. 这些都是一样的。 (The only time it isn't is when using a CIFIlter to "create" something - a color, a tiled image - and then it's infinite.) (唯一一次不是使用CIFIlter“创建”某些东西-颜色,平铺图像-然后是无限的。)
  • A CIVector can have quite a few properties. CIVector可以具有很多属性。 In this case I'm using the X/Y signature, and it's a straight copy of a CGPoint except the Y axis is flipped. 在这种情况下,我使用的是X / Y签名,它是CGPoint的直接副本,只是Y轴被翻转了。
  • I have a sample project here that uses a UIImageView . 这里有一个使用UIImageView示例项目 Be aware that performance on the simulator is nowhere near what performance is on a real device - I recommend using a device anytime CoreImage is involved. 请注意,模拟器的性能远不能与真实设备上的性能相提并论-我建议在涉及CoreImage的任何时候都使用设备。 Also, I did a straight translation from the output CIImage to a UIImage. 另外,我从输出CIImage到UIImage进行了直接转换。 It usually better to use a CIContext and CoreGraphics if you are looking for performance. 如果要提高性能,通常最好使用CIContextCoreGraphics

Given your input, here's the output: 根据您的输入,以下是输出:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM