使用相机会话捕获的裁剪图像
Crop image captured with camera session
我正在尝试裁剪使用相机会话拍摄的具有特定兴趣区域的图像。为了找到比例裁剪矩形,我使用 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)
}
目标矩形:
我不是专家,但我认为您误解了 metadataOutputRectConverted
方法的用法。
您的代码不可能 return 具有相同宽高比的裁剪图像,因为您正在将(我认为是)几乎不相关的数字 相乘。
你可以试试这个方法
previewLayer.layerRectConverted(fromMetadataOutputRect: CGRect(x: 0, y: 0, width: 1, height: 1))
了解 metadataOututRectConverted
的实际计算结果。
我认为你可以更好地解释你想要实现的目标,并可能提供一个示例项目(或者至少提供一些关于你正在使用的实际 images/rects 的更多上下文)来帮助我们调试, 如果您想获得更多帮助。
感谢@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)
}
我正在尝试裁剪使用相机会话拍摄的具有特定兴趣区域的图像。为了找到比例裁剪矩形,我使用 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)
}
目标矩形:
我不是专家,但我认为您误解了 metadataOutputRectConverted
方法的用法。
您的代码不可能 return 具有相同宽高比的裁剪图像,因为您正在将(我认为是)几乎不相关的数字 相乘。
你可以试试这个方法
previewLayer.layerRectConverted(fromMetadataOutputRect: CGRect(x: 0, y: 0, width: 1, height: 1))
了解 metadataOututRectConverted
的实际计算结果。
我认为你可以更好地解释你想要实现的目标,并可能提供一个示例项目(或者至少提供一些关于你正在使用的实际 images/rects 的更多上下文)来帮助我们调试, 如果您想获得更多帮助。
感谢@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)
}