Ios AVF基金会照片大小和旋转

Ios AVF基金会照片大小和旋转,ios,uiimage,avfoundation,avcapturesession,Ios,Uiimage,Avfoundation,Avcapturesession,我正在经历一个噩梦般的时刻,试图纠正一张用AVFoundation拍摄的照片,从Connection到大小和方向与屏幕上显示的完全一致 我使用此代码显示AVCaptureVideoPreviewLayer,以确保它在所有旋转中显示正确的向上方向: previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; [previewLayer setVideoGravity:AVLayerVideoGr

我正在经历一个噩梦般的时刻,试图纠正一张用
AVFoundation
拍摄的照片,从Connection
到大小和方向与屏幕上显示的完全一致

我使用此代码显示
AVCaptureVideoPreviewLayer
,以确保它在所有旋转中显示正确的向上方向:

previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
previewLayer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
if ([[previewLayer connection] isVideoOrientationSupported])
{
    [[previewLayer connection] setVideoOrientation:(AVCaptureVideoOrientation)[UIApplication sharedApplication].statusBarOrientation];
}
[self.view.layer insertSublayer:previewLayer atIndex:0];
现在,当我有一个返回的图像,它需要裁剪,因为它比显示的要大得多。 我知道有大量的
UIImage
裁剪示例,但我遇到的第一个障碍似乎是找到正确的
CGRect
。当我简单地裁剪到
self.view.frame
时,图像被裁剪到了错误的位置

预览使用的是
AVLayerVideoGravityResizeAspectFill
,我的
UIImageView
也设置为
AspectFill

那么,如何从预览层获得屏幕上显示的正确帧

编辑----

这是我面临的问题的一个例子。使用iPad Mini的前置摄像头,摄像头的分辨率为720x1280,但显示屏为768x0124。该视图显示了这一点(请参见图像顶部的护墙板扶手:

然后,当我拍摄图像并显示它时,它看起来是这样的:

// Determine the width:height ratio of the crop rect, based on self.bounds
CGFloat widthToHeightRatio = self.bounds.size.width / self.bounds.size.height;
CGRect cropRect;
// Set the crop rect's smaller dimension to match the image's smaller dimension, and
// scale its other dimension according to the width:height ratio.
if (image.size.width < image.size.height) {
    cropRect.size.width = image.size.width;
    cropRect.size.height = cropRect.size.width / widthToHeightRatio;
} else {
    cropRect.size.width = image.size.height * widthToHeightRatio;
    cropRect.size.height = image.size.height;
}
// Center the rect in the longer dimension
if (cropRect.size.width < cropRect.size.height) {
    cropRect.origin.x = 0;
    cropRect.origin.y = (image.size.height - cropRect.size.height) / 2.0;
} else {
    cropRect.origin.x = (image.size.width - cropRect.size.width) / 2.0;
    cropRect.origin.y = 0;
}


很明显,相机显示在视图的中央,但是裁剪后的图像是从照片的顶部(看不见)部分拍摄的。

我现在正在做一个类似的项目,我想如果你还没有弄明白的话,我可能会帮上忙

我遇到的第一个障碍似乎是找到要使用的正确CGRect。当我简单地剪切到self.view.frame时,图像被剪切到错误的位置

假设您的图像是720x1280,您希望将图像裁剪为显示器的矩形,即大小为768x1024的
CGRect
。您不能只传递大小为768x1024的矩形。首先,您的图像不是768像素宽。其次,您需要指定该矩形相对于图像的位置(即通过指定矩形的原点)。在您的示例中,
self.view.frame
是一个原点为(0,0)的
CGRect
。这就是为什么它总是从图像顶部而不是从中心进行裁剪

计算裁剪矩形有点棘手,因为您有几个不同的坐标系

  • 您已经获得了视图控制器的视图,它具有
  • …作为子层的视频预览层,该层显示的是纵横比填充的图像,但
  • …AVCaptureOutput返回一个
    UIImage
    ,该图像不仅具有与视频预览不同的宽度/高度,而且具有不同的纵横比
因此,由于预览层显示的是居中剪裁的预览图像(即纵横比填充),因此您基本上希望找到的是
CGRect

  • self.view.bounds具有相同的显示比率
  • 具有与
    UIImage
    的较小尺寸相同的较小尺寸(即纵横比匹配)
  • ui图像中居中
比如说:

// Determine the width:height ratio of the crop rect, based on self.bounds
CGFloat widthToHeightRatio = self.bounds.size.width / self.bounds.size.height;
CGRect cropRect;
// Set the crop rect's smaller dimension to match the image's smaller dimension, and
// scale its other dimension according to the width:height ratio.
if (image.size.width < image.size.height) {
    cropRect.size.width = image.size.width;
    cropRect.size.height = cropRect.size.width / widthToHeightRatio;
} else {
    cropRect.size.width = image.size.height * widthToHeightRatio;
    cropRect.size.height = image.size.height;
}
// Center the rect in the longer dimension
if (cropRect.size.width < cropRect.size.height) {
    cropRect.origin.x = 0;
    cropRect.origin.y = (image.size.height - cropRect.size.height) / 2.0;
} else {
    cropRect.origin.x = (image.size.width - cropRect.size.width) / 2.0;
    cropRect.origin.y = 0;
}
//根据self.bounds确定裁剪矩形的宽高比
CGFloat widthttoheightratio=self.bounds.size.width/self.bounds.size.height;
CGRect-cropRect;
//设置裁剪矩形的较小尺寸以匹配图像的较小尺寸,然后
//根据宽高比缩放其其他尺寸。
if(image.size.width

最后,回到你原来的例子,图像是720x1280,你希望你的图像被裁剪成768x1024的矩形,你会得到一个大小为720x960的CGRect,原点是x=0,y=1280-960/2=160。

Richard,我花了两天的时间来解决这个问题,同时拍摄了一张照片使用占屏幕顶部50%的预览层拍照,然后裁剪预览中可见的图像的确切部分。在经历了所有裁剪线程之后,您的是唯一一个工作完美的。谢谢。但有一件事,出于某种原因,我的“cropRect.origin.y”和“cropRect.origin.x”继续得到0个值,但奇怪的是如果我记录它们,它们打印的值是714,所以我必须手动将该数字输入最终的CGRectMake。除此之外,你的代码工作得非常好。酷!很乐意帮忙。这段代码是我动态编写的,只是为了演示这项技术,所以如果你有什么怪癖,我并不感到惊讶结果是y。很高兴你能绕开它!它与除以2有关。我可以让它记录正确的值,但实际的方法不能正确除以2。我对objective-c和一般编程都不熟悉,但它可能只是一个简单的修复方法。不管怎样,我不是在开玩笑。我花了两天时间试图解决这个问题,然后不断收到类似“裁剪图像”的回复。人们只是不理解它,所以再次感谢您的代码。