3

对于我正在开发的应用程序,我让用户指定他们想要在相机上捕获的对象的尺寸(例如 30" x 40")。我要做的下一件事是在其顶部显示带有 cameraOverlayView 的相机源,只显示一个描边透明正方形,该正方形具有正确的比例以捕获该对象。

所以我尝试了两件事来让它工作:

使用 UIViewControllerAVCaptureVideoPreviewLayer来显示带有实时视频源的视图。在该提要的顶部,我显示了一个透明视图,它绘制了一个具有正确尺寸的正方形(使用用户指定的比率)。

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

这两种方法我遇到的主要问题是实际捕获的图像总是比我在屏幕上看到的要大,但我不完全确定在拍摄照片后如何剪掉那张图像.

例如:我的 UIImagePickerController 显示出来了,我在上面放置了一个覆盖层,显示了一个 300 x 400px 大的正方形。用户使用这个正方形拍摄他们的对象的照片并将他们的对象居中在这个正方形内。

图片已拍摄,但不是 320x480(或 640x960)的图片,而是 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 参数中提供正方形的尺寸。

我想到了一些解决方案,但我不确定这是否可行。

  • 将照片缩小到屏幕宽度或高度(以先到者为准),取图片的中心,这与拍照时显示的中心相同吗?不确定这是否可行,我尝试了一点,但失败了。
4

1 回答 1

3

好的,我找到了解决方案:

当您使用相机拍照时,预览屏幕仅显示您正在拍摄的照片的一部分。

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

在此处输入图像描述

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

之后,我剪掉了中间的 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;
}
于 2013-04-25T06:48:18.223 回答