问题描述
我正在尝试为一块薄金属片拍照,并根据屏幕上显示的轮廓进行裁剪。我几乎看过这里的所有其他帖子,但还没有找到适合我的内容。然后,该图像将被图书馆用于分析。我可以进行一些裁剪,但永远不会裁剪显示的矩形。我尝试在裁剪前旋转图像,并根据屏幕上的矩形计算矩形。
这是我的捕获代码。 PreviewView 是容器,videoLayer 用于 AVCapture 视频。
// Photo capture delegate
func photoOutput(_ output: AVCapturePhotoOutput,didFinishProcessingPhoto photo: AVCapturePhoto,error: Error?) {
guard let imgData = photo.fileDataRepresentation(),let uiImg = UIImage(data: imgData),let cgImg = uiImg.cgImage else {
return
}
print("Original image size: ",uiImg.size,"\nCGHeight: ",cgImg.height," width: ",cgImg.width)
print("Orientation: ",uiImg.imageOrientation.rawValue)
guard let img = cropImage(image: uiImg) else {
return
}
showImage(image: img)
}
func cropImage(image: UIImage) -> UIImage? {
print("Image size before crop: ",image.size)
//Get the croppedRect from function below
let croppedRect = calculateRect(image: image)
guard let imgRet = image.cgImage?.cropping(to: croppedRect) else {
return nil
}
return UIImage(cgImage: imgRet)
}
func calculateRect(image: UIImage) -> CGRect {
let originalSize: CGSize
let visibleLayerFrame = self.rectangleView.bounds
// Calculate the rect from the rectangleview to translate to the image
let MetaRect = (self.videoLayer.MetadataOutputRectConverted(fromLayerRect: visibleLayerFrame))
print("MetaRect: ",MetaRect)
// check orientation
if (image.imageOrientation == UIImage.Orientation.left || image.imageOrientation == UIImage.Orientation.right) {
originalSize = CGSize(width: image.size.height,height: image.size.width)
} else {
originalSize = image.size
}
let cropRect: CGRect = CGRect(x: MetaRect.origin.x * originalSize.width,y: MetaRect.origin.y * originalSize.height,width: MetaRect.size.width * originalSize.width,height: MetaRect.size.height * originalSize.height).integral
print("Calculated Rect: ",cropRect)
return cropRect
}
func showImage(image: UIImage) {
if takenImage != nil {
takenImage = nil
}
takenImage = UIImageView(image: image)
takenImage.frame = CGRect(x: 10,y: 50,width: 400,height: 1080)
takenImage.contentMode = .scaleAspectFit
print("Cropped Image Size: ",image.size)
self.previewView.addSubview(takenImage)
}
这是我不断得到的东西。
我在搞什么鬼?
解决方法
UIKit 世界的左上角为 0,0。
AVFoundation 世界中的 0,0 点是左下角。
所以你必须通过旋转 90 度来平移。
这就是为什么你的形象很疯狂。
还请记住,由于原文翻译,以下规则适用:
- X 实际上是上下波动
- Y实际上是左右
- 宽高互换
另请注意,UIImageView 内容模式设置将影响图像的缩放方式。如果您真的想查看图像在 UIView 中的外观,您可能需要使用 .scaleAspectFill 而不是 AspectFit。
我用这个代码片段来看看幕布后面是什么:
// figure out how to cut/crop this
let realImageRect = AVMakeRect(aspectRatio: image.size,insideRect: (self.cameraPreview?.frame)!)
NSLog("real image rectangle = \(realImageRect.debugDescription)")
上面的“cameraPreview”参考是您用于 AV 捕获会话的控件。
祝你好运!