对于我正在开发的应用程序,我让用户指定他们要在相机上捕获的对象的尺寸(例如30“x 40”)。我想做的下一件事情是,在相机源上显示有cameraOverlayView,除了划过的透明正方形外,什么都没显示,该正方形具有正确的比例来捕获该对象。

,所以我尝试了两件事使它起作用:

使用UIViewController,它使用AVCaptureVideoPreviewLayer显示带有实时视频供稿的视图。在该提要的顶部,我显示一个透明视图,该视图以正确的尺寸(使用用户指定的比例)绘制一个正方形。



在另一种尝试中,我创建了一个UIViewController,其中包含一个弹出UIImagePickerController的按钮。使用此控制器,我还创建了一个视图,并使用cameraOverlayView属性将其附加到选择器。

这两种方法的主要问题是,实际捕获的图像总是比我在屏幕上看到的大,但是我不确定在拍摄照片后如何裁剪出那部分图像。 。

因此,例如:
显示了我的UIImagePickerController,我在上面覆盖了一个叠加层,显示了一个300 x 400px大的正方形。用户使用该正方形来拍摄其对象的图片并将其对象居中于该正方形内。

拍摄了照片,但是得到的结果不是3500x2400(或类似的东西),而不是320x480(或640x960)的照片。它的比率与屏幕比率(当然)完全不同。

然后,如何确保切出图像的正确部分。

实际计算应显示的正方形大小的代码(并应用于确定应剪切图片的哪一部分):

+ (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设备处于纵向模式时,照片高度将缩小到屏幕高度,并且仅显示中间的640px。

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

    之后,我将中间的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;
    }
    

    10-07 19:55
    查看更多