UIImagePickerController 不填满屏幕

发布于 2024-08-29 16:47:42 字数 1197 浏览 4 评论 0原文

screenshot

我正在向 UIImagePickerController 添加自定义叠加层,并且视图底部有一个持续的黑条。这是我实例化控制器的代码。

- (UIImagePickerController *)imagePicker {
    if (_imagePicker) {
        return _imagePicker;
    }

    _imagePicker = [[UIImagePickerController alloc] init];
    _imagePicker.delegate = self;

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        _imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;

        _imagePicker.showsCameraControls = NO;

        _imagePicker.wantsFullScreenLayout = YES;
        _imagePicker.navigationBarHidden = YES;
        _imagePicker.toolbarHidden = YES;

    } else {
        _imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }

    return _imagePicker;
}

当我不隐藏相机控件时,返回的控制器以模态方式显示并且工作得很好(即显示全屏)。


感谢 Ole 的建议,我得到了它与此代码的工作:

// Resize the camera preview
        _imagePicker.cameraViewTransform = CGAffineTransformMakeScale(1.0, 1.03);

高度增加 3% 效果很好。当我在屏幕底部添加自定义工具栏时,窗口中不再有可见的黑条。

screenshot

I'm adding a custom overlay to the UIImagePickerController and there is a persistant black bar at the bottom of the view. Here is my code to instantiate the controller.

- (UIImagePickerController *)imagePicker {
    if (_imagePicker) {
        return _imagePicker;
    }

    _imagePicker = [[UIImagePickerController alloc] init];
    _imagePicker.delegate = self;

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        _imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;

        _imagePicker.showsCameraControls = NO;

        _imagePicker.wantsFullScreenLayout = YES;
        _imagePicker.navigationBarHidden = YES;
        _imagePicker.toolbarHidden = YES;

    } else {
        _imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }

    return _imagePicker;
}

The returned controller is displayed modally and works just fine (i.e. displays full screen) when I'm not hiding the camera controls.


Thanks to Ole's suggestion I got it working with this code:

// Resize the camera preview
        _imagePicker.cameraViewTransform = CGAffineTransformMakeScale(1.0, 1.03);

A 3% increase in height worked just fine. When I add my custom toolbar at the bottom of the screen there is no longer a visible black bar across the window.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

两仪 2024-09-05 16:47:43

尝试使用此代码:

picker.wantsFullScreenLayout = YES;
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0);
CGAffineTransform scale = CGAffineTransformScale(translate, 1.333333, 1.47);
picker.view.transform = scale;

Try use this code:

picker.wantsFullScreenLayout = YES;
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0);
CGAffineTransform scale = CGAffineTransformScale(translate, 1.333333, 1.47);
picker.view.transform = scale;
久隐师 2024-09-05 16:47:43
PickerViewController.m    
#define CAMERA_TRANSFORM  1.8

- (void)viewDidAppear:(BOOL)animated
{
 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
       // type = UIImagePickerControllerSourceTypeCamera;

        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.allowsEditing = NO;
        picker.delegate   = self;
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        picker.showsCameraControls=NO;
        picker.extendedLayoutIncludesOpaqueBars = YES;
        picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, CAMERA_TRANSFORM , CAMERA_TRANSFORM);

        [self presentViewController:picker animated:YES completion:nil];
    }else{

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Message"
                                                        message:@"Device have no camera"
                                                       delegate:self
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }
}
PickerViewController.m    
#define CAMERA_TRANSFORM  1.8

- (void)viewDidAppear:(BOOL)animated
{
 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
       // type = UIImagePickerControllerSourceTypeCamera;

        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.allowsEditing = NO;
        picker.delegate   = self;
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        picker.showsCameraControls=NO;
        picker.extendedLayoutIncludesOpaqueBars = YES;
        picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, CAMERA_TRANSFORM , CAMERA_TRANSFORM);

        [self presentViewController:picker animated:YES completion:nil];
    }else{

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Message"
                                                        message:@"Device have no camera"
                                                       delegate:self
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }
}
短叹 2024-09-05 16:47:42

按固定值缩放并不是一个好主意...因为我确信使用此处接受的答案的任何人都可能在 iPhone 5 推出时发现了这一点。

这是一个根据屏幕分辨率动态缩放以消除字母框的代码片段。

// Device's screen size (ignoring rotation intentionally):
CGSize screenSize = [[UIScreen mainScreen] bounds].size;

// iOS is going to calculate a size which constrains the 4:3 aspect ratio
// to the screen size. We're basically mimicking that here to determine
// what size the system will likely display the image at on screen.
// NOTE: screenSize.width may seem odd in this calculation - but, remember,
// the devices only take 4:3 images when they are oriented *sideways*.
float cameraAspectRatio = 4.0 / 3.0;
float imageWidth = floorf(screenSize.width * cameraAspectRatio);
float scale = ceilf((screenSize.height / imageWidth) * 10.0) / 10.0;

self.ipc.cameraViewTransform = CGAffineTransformMakeScale(scale, scale);

Scaling by a fixed value isn't a good idea... as I'm sure anyone who used the accepted answer here probably found out when the iPhone 5 came out.

Here's a code snippet to scale dynamically based on the screen resolution to eliminate the letter boxing.

// Device's screen size (ignoring rotation intentionally):
CGSize screenSize = [[UIScreen mainScreen] bounds].size;

// iOS is going to calculate a size which constrains the 4:3 aspect ratio
// to the screen size. We're basically mimicking that here to determine
// what size the system will likely display the image at on screen.
// NOTE: screenSize.width may seem odd in this calculation - but, remember,
// the devices only take 4:3 images when they are oriented *sideways*.
float cameraAspectRatio = 4.0 / 3.0;
float imageWidth = floorf(screenSize.width * cameraAspectRatio);
float scale = ceilf((screenSize.height / imageWidth) * 10.0) / 10.0;

self.ipc.cameraViewTransform = CGAffineTransformMakeScale(scale, scale);
究竟谁懂我的在乎 2024-09-05 16:47:42

相机的长宽比为4:3,屏幕的长宽比为3:2。因此,除非您愿意将相机图片裁剪为 3:2,否则根本无法让相机图片填满屏幕。为此,请应用适当的比例变换。

The camera's aspect ratio is 4:3 and the screen's aspect ratio is 3:2. So there is simply no way for the camera picture to fill the screen unless you're willing to crop is to 3:2. To do that, apply an appropriate scale transform.

冷弦 2024-09-05 16:47:42

嘿,我看到有些人在计算 iPhone 5 的比例后仍然出现底部的黑条。我遇到这个问题有一段时间了,但后来我发现你必须翻译视图,使其位于屏幕中间然后应用比例。这是我执行这两件事的代码,它对我有用!

    CGSize screenBounds = [UIScreen mainScreen].bounds.size;

    CGFloat cameraAspectRatio = 4.0f/3.0f;

    CGFloat camViewHeight = screenBounds.width * cameraAspectRatio;
    CGFloat scale = screenBounds.height / camViewHeight;

    m_imagePickerController.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenBounds.height - camViewHeight) / 2.0);
    m_imagePickerController.cameraViewTransform = CGAffineTransformScale(m_imagePickerController.cameraViewTransform, scale, scale);

Hey I saw some people were still getting the black bar at the bottom after calculating the scale for the iPhone 5. I had this problem for a while but then I figured out you have to translate the view so it is in the middle of the screen and then apply the scale. Here is my code for doing those two things and it works for me!

    CGSize screenBounds = [UIScreen mainScreen].bounds.size;

    CGFloat cameraAspectRatio = 4.0f/3.0f;

    CGFloat camViewHeight = screenBounds.width * cameraAspectRatio;
    CGFloat scale = screenBounds.height / camViewHeight;

    m_imagePickerController.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenBounds.height - camViewHeight) / 2.0);
    m_imagePickerController.cameraViewTransform = CGAffineTransformScale(m_imagePickerController.cameraViewTransform, scale, scale);
最舍不得你 2024-09-05 16:47:42

根据我在 iOS 7、iPhone 5S 上的经验,要在全屏预览中看到图片的中心,您必须连接转换,而不是按顺序进行转换:

pickerController.cameraOverlayView = self.view;

CGSize screenSize = [[UIScreen mainScreen] bounds].size;   // 320 x 568

float scale = screenSize.height / screenSize.width*3/4;  // screen height divided by the pickerController height ... or:  568 / ( 320*4/3 )

CGAffineTransform translate=CGAffineTransformMakeTranslation(0,(screenSize.height - screenSize.width*4/3)*0.5);
CGAffineTransform fullScreen=CGAffineTransformMakeScale(scale, scale);
pickerController.cameraViewTransform =CGAffineTransformConcat(fullScreen, translate);

From my experience on iOS 7, iphone 5S, to see the center of the picture into the full-screen preview you have to concatenate the transformations, not make them sequentially:

pickerController.cameraOverlayView = self.view;

CGSize screenSize = [[UIScreen mainScreen] bounds].size;   // 320 x 568

float scale = screenSize.height / screenSize.width*3/4;  // screen height divided by the pickerController height ... or:  568 / ( 320*4/3 )

CGAffineTransform translate=CGAffineTransformMakeTranslation(0,(screenSize.height - screenSize.width*4/3)*0.5);
CGAffineTransform fullScreen=CGAffineTransformMakeScale(scale, scale);
pickerController.cameraViewTransform =CGAffineTransformConcat(fullScreen, translate);
a√萤火虫的光℡ 2024-09-05 16:47:42

用这个来改变它:

#define CAMERA_TRANSFORM                    1.12412

_picker.wantsFullScreenLayout = YES;
_picker.cameraViewTransform = CGAffineTransformScale(_picker.cameraViewTransform, CAMERA_TRANSFORM, CAMERA_TRANSFORM);

Transform it with this:

#define CAMERA_TRANSFORM                    1.12412

_picker.wantsFullScreenLayout = YES;
_picker.cameraViewTransform = CGAffineTransformScale(_picker.cameraViewTransform, CAMERA_TRANSFORM, CAMERA_TRANSFORM);
俯瞰星空 2024-09-05 16:47:42

这是 Swift 的答案。

let screenSize:CGSize = UIScreen.mainScreen().bounds.size

let ratio:CGFloat = 4.0 / 3.0
let cameraHeight:CGFloat = screenSize.width * ratio
let scale:CGFloat = screenSize.height / cameraHeight

let imag:UIImagePickerController = UIImagePickerController()
imag.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenSize.height - cameraHeight) / 2.0)
imag.cameraViewTransform = CGAffineTransformScale(imag.cameraViewTransform, scale, scale)

And here the answer in Swift.

let screenSize:CGSize = UIScreen.mainScreen().bounds.size

let ratio:CGFloat = 4.0 / 3.0
let cameraHeight:CGFloat = screenSize.width * ratio
let scale:CGFloat = screenSize.height / cameraHeight

let imag:UIImagePickerController = UIImagePickerController()
imag.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenSize.height - cameraHeight) / 2.0)
imag.cameraViewTransform = CGAffineTransformScale(imag.cameraViewTransform, scale, scale)
只是一片海 2024-09-05 16:47:42

这在 iOS 10 上对我有用:

let screenSize = UIScreen.main.bounds.size
let cameraAspectRatio = CGFloat(4.0 / 3.0)
let cameraImageHeight = screenSize.width * cameraAspectRatio
let scale = screenSize.height / cameraImageHeight
imagePickerController.cameraViewTransform = CGAffineTransform(translationX: 0, y: (screenSize.height - cameraImageHeight)/2)
imagePickerController.cameraViewTransform = imagePickerController.cameraViewTransform.scaledBy(x: scale, y: scale)

This worked for me on iOS 10:

let screenSize = UIScreen.main.bounds.size
let cameraAspectRatio = CGFloat(4.0 / 3.0)
let cameraImageHeight = screenSize.width * cameraAspectRatio
let scale = screenSize.height / cameraImageHeight
imagePickerController.cameraViewTransform = CGAffineTransform(translationX: 0, y: (screenSize.height - cameraImageHeight)/2)
imagePickerController.cameraViewTransform = imagePickerController.cameraViewTransform.scaledBy(x: scale, y: scale)
你丑哭了我 2024-09-05 16:47:42

我用这个方法来计算比例。

// get the screen size
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// establish the height to width ratio of the camera
float heightRatio = 4.0f / 3.0f;
// calculate the height of the camera based on the screen width
float cameraHeight = screenSize.width * heightRatio;
// calculate the ratio that the camera height needs to be scaled by
float scale = screenSize.height / cameraHeight;
imagePicker.cameraViewTransform = CGAffineTransformMakeScale(scale, scale);

I used this method to calculate the scale.

// get the screen size
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// establish the height to width ratio of the camera
float heightRatio = 4.0f / 3.0f;
// calculate the height of the camera based on the screen width
float cameraHeight = screenSize.width * heightRatio;
// calculate the ratio that the camera height needs to be scaled by
float scale = screenSize.height / cameraHeight;
imagePicker.cameraViewTransform = CGAffineTransformMakeScale(scale, scale);
墨落画卷 2024-09-05 16:47:42

我的问题解决了:)

//Camera is 426 * 320. Screen height is 568.  Multiply by 1.333 in 5 inch (iPhone5) to fill vertical

CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0); //This slots the preview exactly in the middle of the screen by moving it down 71 points
self.imagePickerController.cameraViewTransform = translate;

CGAffineTransform scale = CGAffineTransformScale(translate, 1.333333, 1.333333);
self.imagePickerController.cameraViewTransform = scale;

my issue solved :)

//Camera is 426 * 320. Screen height is 568.  Multiply by 1.333 in 5 inch (iPhone5) to fill vertical

CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0); //This slots the preview exactly in the middle of the screen by moving it down 71 points
self.imagePickerController.cameraViewTransform = translate;

CGAffineTransform scale = CGAffineTransformScale(translate, 1.333333, 1.333333);
self.imagePickerController.cameraViewTransform = scale;
习惯成性 2024-09-05 16:47:42

这些解决方案对我来说并不完全有效。在 iOS 13.x 下运行并使用 iPhone 6+ 和 iPhone 11 Pro 时,底部仍然有黑条。我能够通过计算中心偏移并将其应用于比例计算来解决这两个问题,而无需使用幻数。这在 6+ 和 11 Pro 上再次有效。

    let screenSize = UIScreen.main.bounds.size
    let cameraAspectRatio = CGFloat(4.0 / 3.0)
    let cameraImageHeight = screenSize.width * cameraAspectRatio
    let offsetToCenter = screenSize.height - cameraImageHeight
    let scale = (screenSize.height + offsetToCenter) / cameraImageHeight

    if UIImagePickerController.isSourceTypeAvailable(.camera) {
        myPickerController.delegate = self
        myPickerController.sourceType = .camera
        myPickerController.showsCameraControls = false
        myPickerController.allowsEditing = false
        myPickerController.cameraViewTransform = CGAffineTransform(scaleX: scale, y: scale)
        myPickerController.cameraOverlayView = CameraOverlay(frame: vc.view.frame, delegate: self)
        currentVC.present(myPickerController, animated: true)
    }
}

These solutions did not work in total for me. There was still a black bar at the bottom running under iOS 13.x and using an iPhone 6+ and an iPhone 11 Pro. I was able to resolve for both, without using magic numbers, by calculating the offset to center and applying that to the scale calculation. This worked again with both a 6+ and an 11 Pro.

    let screenSize = UIScreen.main.bounds.size
    let cameraAspectRatio = CGFloat(4.0 / 3.0)
    let cameraImageHeight = screenSize.width * cameraAspectRatio
    let offsetToCenter = screenSize.height - cameraImageHeight
    let scale = (screenSize.height + offsetToCenter) / cameraImageHeight

    if UIImagePickerController.isSourceTypeAvailable(.camera) {
        myPickerController.delegate = self
        myPickerController.sourceType = .camera
        myPickerController.showsCameraControls = false
        myPickerController.allowsEditing = false
        myPickerController.cameraViewTransform = CGAffineTransform(scaleX: scale, y: scale)
        myPickerController.cameraOverlayView = CameraOverlay(frame: vc.view.frame, delegate: self)
        currentVC.present(myPickerController, animated: true)
    }
}
岁月无声 2024-09-05 16:47:42

Swift 5

100% 工作
简单的解决方案
如果您想在某些自定义 UIView 中显示相机,请使用该代码,相机将在全屏中显示,

class ViewController: UIViewController, UINavigationControllerDelegate,UIImagePickerControllerDelegate {


}

上部用于代表,底部用于功能,

//Mark:- Call this function and enjoy
var imagePickers:UIImagePickerController?
func addCameraInView(){
    imagePickers = UIImagePickerController()
    if UIImagePickerController.isCameraDeviceAvailable( UIImagePickerController.CameraDevice.rear) {
        imagePickers?.delegate = self
        imagePickers?.sourceType = UIImagePickerController.SourceType.camera
        //imagePickers?.view.frame = customCameraView.bounds
        imagePickers?.view.contentMode = .scaleAspectFit
        imagePickers?.allowsEditing = false
        imagePickers?.showsCameraControls = false
        imagePickers?.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

       //Mark:- this part is handling camera in full screen in a custom view
       // let screenSize = UIScreen.main.bounds.size
        let screenSize = customCameraView.bounds.size
        let cameraAspectRatio = CGFloat(4.0 / 4.0)
        let cameraImageHeight = screenSize.width * cameraAspectRatio
        let scale = screenSize.height / cameraImageHeight
        imagePickers?.cameraViewTransform = CGAffineTransform(translationX: 0, y: (screenSize.height - cameraImageHeight)/2)
        imagePickers?.cameraViewTransform = (imagePickers?.cameraViewTransform.scaledBy(x: scale, y: scale))!

        // Add the child's View as a subview
        self.customCameraView.addSubview((imagePickers?.view)!)
    }
}

如果您希望从主屏幕显示,则需要更改比率 (4.0/3.0)

   let screenSize = UIScreen.main.bounds.size
   let cameraAspectRatio = CGFloat(4.0 / 3.0)

< a href="https://i.sstatic.net/nwLIB.jpg" rel="nofollow noreferrer">输入图像描述这里

Swift 5

100% working
Easy Solution
If you want show camera in some custom UIView so use that code and camera will be show in full screen

class ViewController: UIViewController, UINavigationControllerDelegate,UIImagePickerControllerDelegate {


}

upper section is for delegate and bottom is function

//Mark:- Call this function and enjoy
var imagePickers:UIImagePickerController?
func addCameraInView(){
    imagePickers = UIImagePickerController()
    if UIImagePickerController.isCameraDeviceAvailable( UIImagePickerController.CameraDevice.rear) {
        imagePickers?.delegate = self
        imagePickers?.sourceType = UIImagePickerController.SourceType.camera
        //imagePickers?.view.frame = customCameraView.bounds
        imagePickers?.view.contentMode = .scaleAspectFit
        imagePickers?.allowsEditing = false
        imagePickers?.showsCameraControls = false
        imagePickers?.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

       //Mark:- this part is handling camera in full screen in a custom view
       // let screenSize = UIScreen.main.bounds.size
        let screenSize = customCameraView.bounds.size
        let cameraAspectRatio = CGFloat(4.0 / 4.0)
        let cameraImageHeight = screenSize.width * cameraAspectRatio
        let scale = screenSize.height / cameraImageHeight
        imagePickers?.cameraViewTransform = CGAffineTransform(translationX: 0, y: (screenSize.height - cameraImageHeight)/2)
        imagePickers?.cameraViewTransform = (imagePickers?.cameraViewTransform.scaledBy(x: scale, y: scale))!

        // Add the child's View as a subview
        self.customCameraView.addSubview((imagePickers?.view)!)
    }
}

if you want it from main screen then you need to change the ratio (4.0/3.0)

   let screenSize = UIScreen.main.bounds.size
   let cameraAspectRatio = CGFloat(4.0 / 3.0)

enter image description here

嗳卜坏 2024-09-05 16:47:42

这就是 Swift 4 对我有用的东西

let screenSize: CGSize = picker.view.safeAreaLayoutGuide.layoutFrame.size
let ratio: CGFloat = 4.0 / 3.0
let cameraHeight: CGFloat = screenSize.width * ratio
let scale: CGFloat = (screenSize.height + 80) / cameraHeight
picker.cameraViewTransform = picker.cameraViewTransform.scaledBy(x: scale, y: scale)

This is what works for me with Swift 4

let screenSize: CGSize = picker.view.safeAreaLayoutGuide.layoutFrame.size
let ratio: CGFloat = 4.0 / 3.0
let cameraHeight: CGFloat = screenSize.width * ratio
let scale: CGFloat = (screenSize.height + 80) / cameraHeight
picker.cameraViewTransform = picker.cameraViewTransform.scaledBy(x: scale, y: scale)
許願樹丅啲祈禱 2024-09-05 16:47:42

以下工作对我来说可以消除信箱并捕获与精确设备高度匹配的全屏图像。该代码是用 Swift 5 编写的。

 // Eliminate letter boxing
 let screenSize = UIScreen.main.bounds
 let cameraAspectRatio: CGFloat = 4.0 / 3.0
 let imageHeight = screenSize.width * cameraAspectRatio
 let scale = ceil((screenSize.height / imageHeight) * 10.0) / 10.0
 var transform = CGAffineTransform(translationX: 0, y: (screenSize.height - imageHeight) / 2)
 transform = transform.scaledBy(x: scale, y: scale)
 picker.cameraViewTransform = transform

Following works for me to eliminate Letter boxing and capture full screen images matching exact device height. The code is written in Swift 5.

 // Eliminate letter boxing
 let screenSize = UIScreen.main.bounds
 let cameraAspectRatio: CGFloat = 4.0 / 3.0
 let imageHeight = screenSize.width * cameraAspectRatio
 let scale = ceil((screenSize.height / imageHeight) * 10.0) / 10.0
 var transform = CGAffineTransform(translationX: 0, y: (screenSize.height - imageHeight) / 2)
 transform = transform.scaledBy(x: scale, y: scale)
 picker.cameraViewTransform = transform
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文