从相机中剪下预定义的一张照片

问题描述:

对于我正在开发的应用程序,我让用户指定他们想要在相机上捕捉的对象的尺寸(例如30“x 40”)。接下来我想要做的是在相机上显示一个cameraOverlayView,它只显示一个抚摸透明的正方形,它具有正确的比例来捕捉该物体。从相机中剪下预定义的一张照片

所以,我想两件事情得到这个工作:

使用它使用AVCaptureVideoPreviewLayer显示与现场视频馈送视图一个UIViewController。在该提要之上,我显示一个透明视图,该视图用正确的尺寸绘制一个正方形(使用用户指定的比例)。

在另一种尝试中,我创建一个UIViewController,含有一个按钮,弹出UIImagePickerController。使用这个控制器,我还创建了一个视图,我使用cameraOverlayView属性附加到选取器。

我对这两种方法的主要问题是,实际拍摄的图像总是比我在屏幕上看到的图像大,但我不完全确定如何切割出图像后的照片已被拍摄。

因此,例如: 我的UIImagePickerController显示,我把一个覆盖,显示一个300 x 400px大的正方形。用户使用这个方块拍摄他们的物体的照片,并将它们的物体置于这个方块内。

的拍摄照片,但不是照片是小320x480(或640×960),我得到的结果是3500x2400(或类似的东西。这是一个完全不同的比率,则屏幕比例(当然)。

我怎么然后确保我切出的图像的右侧部分。

实际计算应显示(而且应该被用来确定应该是什么样件图片的平方大小的代码剪下):

+ (CGRect) getFrameRect:(CGRect) rect forSize:(CGSize) frameSize { 
    if (CGSizeEqualToSize(frameSize, CGSizeZero)) 
     return CGRectZero; 

    float maxWidth = rect.size.width - 20; 
    float maxHeight = rect.size.height - 20; 

    float ratioX = maxWidth/frameSize.width; 
    float ratioY = maxHeight/frameSize.height; 
    float ratio = MIN(ratioX, ratioY); 

    float newWidth = frameSize.width * ratio; 
    float newHeight = frameSize.height * ratio; 

    float x = (rect.size.width - newWidth)/2; 
    float y = (rect.size.height - newHeight)/2; 

    return CGRectMake(x, y, newWidth, newHeight); 
} 

这决定了可以使用frameSize参数中指定的比率创建的最大正方形,其中应在rect参数中提供正方形的尺寸。

一些解决方案浮现在脑海,但我不确定这是否可行。

  • 将照片缩小到屏幕宽度或高度(无论先出现哪个),以图片的中心为准,这与拍摄照片时显示的中心相同?不知道这会起作用,我试了一下,但失败了。

好吧,我找到了解决办法:

当你正在使用相机拍摄照片,预览屏幕只显示你正在服用的照片的一部分。

当您的iOS设备处于肖像模式时,照片高度将缩小到屏幕高度,并且只显示中间的640像素。

enter image description here

的暗红色部分是什么是显示在屏幕上。因此,当您拍摄照片时,您需要将图像缩小到屏幕的最大高度以获得正确的宽度。

之后,我切出中间640x960像素,以实际获得与拍摄照片时所显示的相同的图像。

之后,我的矩形覆盖图的坐标与我的覆盖图的坐标相同。

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    [picker dismissModalViewControllerAnimated:YES]; 

    UIImage* artImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 


    CGFloat imageHeightRatio = artImage.size.height/960; 
    CGFloat imageWidth = artImage.size.width/imageHeightRatio; 

    CGSize newImageSize = CGSizeMake(imageWidth, 960); 
    artImage = [artImage imageByScalingProportionallyToSize:newImageSize]; 

    CGRect cutOutRect = CGRectMake((artImage.size.width/2) - (640/2), 0, 640, 960); 

    artImage = [self imageByCropping:artImage toRect:cutOutRect]; 

    CGRect imageCutRect = [FrameSizeCalculations getFrameRect:CGRectMake(0,0, artImage.size.width, artImage.size.height) forSize:self.frameSize]; 
    artImage = [self imageByCropping:artImage toRect:imageCutRect]; 

    CGRect imageViewRect = CGRectInset(_containmentView.bounds, 10, 10); 

    NSLog(@"ContainmentView: %f x %f x %f x %f", 
      _containmentView.frame.origin.x, 
      _containmentView.frame.origin.y, 
      _containmentView.frame.size.width, 
      _containmentView.frame.size.height 
     ); 

    NSLog(@"imageViewRect: %f x %f x %f x %f", 
      imageViewRect.origin.x, 
      imageViewRect.origin.y, 
      imageViewRect.size.width, 
      imageViewRect.size.height 
     ); 

    _imageView.frame = [FrameSizeCalculations getFrameRect:imageViewRect forSize:self.frameSize]; 

    NSLog(@"imageViewRect: %f x %f x %f x %f", 
      _imageView.frame.origin.x, 
      _imageView.frame.origin.y, 
      _imageView.frame.size.width, 
      _imageView.frame.size.height 
     ); 

    _imageView.contentMode = UIViewContentModeScaleAspectFill; 
    _imageView.image = artImage; 
}