AVFoundation 照片大小和旋转
Posted
技术标签:
【中文标题】AVFoundation 照片大小和旋转【英文标题】:AVFoundation photo size and rotation 【发布时间】:2014-01-11 11:13:09 【问题描述】:我正经历着噩梦般的时光,试图将使用 AVFoundation
captureStillImageAsynchronouslyFromConnection
拍摄的照片校正为屏幕上显示的大小和方向。
我用这段代码显示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
那么我怎样才能从预览层获得AVFoundation
在屏幕上显示的正确帧?
编辑----
这是我面临的问题的一个示例。使用 iPad Mini 的前置摄像头,摄像头使用分辨率 720x1280,但显示屏为 768x0124。视图显示了这一点(参见图片顶部的墙板:
然后当我拍摄图像并显示它时,它看起来像这样:
显然相机显示在视图的中心,但裁剪后的图像是从照片的顶部(看不到)部分拍摄的。
【问题讨论】:
【参考方案1】:我现在正在做一个类似的项目,如果你还没有弄清楚的话,我想我可能会提供帮助。
我似乎遇到的第一个障碍是找到要使用的正确 CGRect。当我简单地裁剪到 self.view.frame 时,图像被裁剪在错误的位置。
假设您的图片为 720x1280,并且您希望将图片裁剪为显示器的矩形,即尺寸为 768x1024 的 CGRect
。你不能只传递一个大小为 768x1024 的矩形。首先,您的图像不是 768 像素宽。其次,您需要指定该矩形相对于图像的位置(即通过指定矩形的原点)。在您的示例中,self.view.frame
是一个原点为 (0, 0) 的 CGRect
。这就是为什么它总是从图像的顶部而不是从中心裁剪。
计算裁剪矩形有点棘手,因为您有几个不同的坐标系。
您已经获得了视图控制器的视图,它具有... ...一个视频预览层作为子层,它正在显示一个方面填充的图像,但是... ...AVCaptureOutput
返回一个UIImage
,它不仅具有与视频预览不同的宽度/高度,而且还具有不同的纵横比。
因此,由于您的预览层显示的是居中且裁剪后的预览图像(即方面填充),因此您基本上想要找到的是 CGRect
:
self.view.bounds
相同
具有与UIImage
的较小尺寸相同的较小尺寸(即方面适合)
以UIImage
为中心
所以是这样的:
// 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;
最后,回到图像为 720x1280 的原始示例,并且您希望将图像裁剪为 768x1024 的显示矩形,您最终将得到一个大小为 720x960 的 CGRect,其x 的原点 = 0,y = 1280-960/2 = 160。
【讨论】:
Richard,我刚刚花了 2 天时间尝试解决同样的问题,同时拍摄一张预览层占据屏幕顶部 50% 的照片,然后裁剪图像的确切部分在预览中可见。在浏览了 SO 上的每个裁剪线程之后,您的线程是唯一一个可以完美运行的线程。谢谢。 有一件事,由于某种原因,我的“cropRect.origin.y”和“cropRect.origin.x”都得到0值,但奇怪的是,如果我用NSLog它们打印一个值714 所以我不得不手动将该数字输入到最终的 CGRectMake 中。除此之外,您的代码运行良好。 酷!乐意效劳。那段代码是我为了演示该技术而临时编写的,所以如果你得到一些古怪的结果,我并不感到惊讶。很高兴你设法绕过它! 它与除以 2 有关。我可以将它提供给 NSLog 正确的值,但实际方法不能正确除以 2。我是 Objective-c 和一般编程的新手,但这可能只是一个简单的修复。不管怎样,我不是在开玩笑。我花了 2 天时间试图弄清楚这一点,并不断收到诸如“裁剪图像”之类的回复。人们只是不明白,所以再次感谢您提供此代码。以上是关于AVFoundation 照片大小和旋转的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iphone 中使用 avFoundation 像 Instagram 应用一样拍摄方形照片?