【问题标题】:Crop image captured with camera session使用相机会话捕获的裁剪图像
【发布时间】:2020-03-01 04:32:16
【问题描述】:

我正在尝试裁剪具有特定兴趣区域的相机会话捕获的图像。为了找到比例裁剪矩形,我使用previewLayer.metadataOutputRectConverted 方法。但裁剪后我得到了错误的比例。

调试示例:

(lldb) po rectOfInterest.width / rectOfInterest.height
0.7941176470588235

(lldb) po image.size.width / image.size.height
0.75

(lldb) po outputRect.width / outputRect.height
0.9444444444444444

(lldb) po Double(cropped.width) / Double(cropped.height)
0.7080152671755725

如您所见,我预计裁剪后的图像比例将是 ~0.79 和我用于裁剪的 rectOfInterest

方法:

private func makeImageCroppedToRectOfInterest(from image: UIImage) -> UIImage {
    let previewLayer = cameraController.previewLayer
    let rectOfInterest = layoutLayer.layoutRect

    let outputRect = previewLayer.metadataOutputRectConverted(fromLayerRect: rectOfInterest)

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

    let width = CGFloat(cgImage.width)
    let height = CGFloat(cgImage.height)

    let cropRect = CGRect(x: outputRect.origin.x * width,
                          y: outputRect.origin.y * height ,
                          width: outputRect.size.width * width,
                          height: outputRect.size.height * height)

    guard let cropped = cgImage.cropping(to: cropRect) else {
        return image
    }

    return UIImage(cgImage: cropped, scale: image.scale, orientation: image.imageOrientation)
}

目标矩形:

【问题讨论】:

    标签: ios swift image camera crop


    【解决方案1】:

    感谢@Enricoza,我知道如何解决我的问题。这是代码:

    private func makeImageCroppedToRectOfInterest(from image: UIImage) -> UIImage {
            let previewLayer = cameraController.previewLayer
            let rectOfInterest = layoutLayer.layoutRect
    
            let metadataOutputRect = CGRect(x: 0, y: 0, width: 1, height: 1)
            let outputRect = previewLayer.layerRectConverted(fromMetadataOutputRect: metadataOutputRect)
    
            guard let cgImage = image.cgImage else {
                return image
            }
    
            let width = image.size.width
            let height = image.size.height
    
            let factorX = width / outputRect.width
            let factorY = height / outputRect.height
            let factor = max(factorX, factorY)
    
            let cropRect = CGRect(x: (rectOfInterest.origin.x - outputRect.origin.x) * factor,
                                  y: (rectOfInterest.origin.y - outputRect.origin.y) * factor,
                                  width: rectOfInterest.size.width * factor,
                                  height: rectOfInterest.size.height * factor)
    
            guard let cropped = cgImage.cropping(to: cropRect) else {
                return image
            }
    
            return UIImage(cgImage: cropped, scale: image.scale, orientation: image.imageOrientation)
        }
    

    【讨论】:

    • 此代码裁剪捕获的图像,其中: 1. rectOfInterest – 您要保留在结果图像中的矩形 2. outputRect – 实际捕获的矩形(这不是您在屏幕上看到的)
    • 我不完全确定这实际上适用于每个矩形,但如果你这么说我相信你:D
    • cropRect 的 Y 计算不正确。然而,X 是。我裁剪的图像似乎水平裁剪正确,但垂直不正确!
    【解决方案2】:

    我不是专家,但我认为您误解了 metadataOutputRectConverted 方法的用法。 您的代码无法返回具有相同纵横比的裁剪图像,因为您将(我认为是)实际上不相关的数字彼此相乘。

    你可以试试这个方法

    previewLayer.layerRectConverted(fromMetadataOutputRect: CGRect(x: 0, y: 0, width: 1, height: 1))
    

    了解从metadataOututRectConverted 进行的实际计算是什么。

    我认为您可以更好地解释您想要实现的目标,并且可以提供一个示例项目(或者至少提供更多关于您正在使用的实际图像/矩形的上下文)来帮助我们调试,如果您愿意的话在这方面获得更多帮助。

    【讨论】:

    • 我有AVCaptureVideoPreviewLayer,它显示了相机捕捉区域,另外我在相机预览层内有“目标”矩形,它小于相机预览层的矩形。结果我想得到完全相同的图片,用户在我的“目标矩形”中看到
    • 我稍后会尝试,同时你能提供一个示例项目吗?
    • 我添加了我的相机预览层的截图。如您所见,我有实际的相机捕捉矩形(暗区),我有目标矩形(亮区)。
    • previewLayer.layerRectConverted(fromMetadataOutputRect: CGRect(x: 0, y: 0, width: 1, height: 1)) 不适合,因为我没有关于元数据输出矩形的数据
    猜你喜欢
    • 1970-01-01
    • 2013-05-26
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 2016-12-27
    • 1970-01-01
    相关资源
    最近更新 更多