iOS Monotouch UIImagePickerController来自相机的多张照片/视频

 youxiang574传奇_257 发布于 2023-02-11 17:21

我们遇到了一个UIImagePickerController的奇怪问题.在我们的应用程序中,用户可以填写一系列表格,还可以在这些表格中附加图像和视频.

我们允许用户从相机胶卷添加多张照片/视频,或者在填写表格时进行拍摄.

我们正在使用UIImagePickerController执行此操作.使用相机拍摄1或2张图像/视频时会出现问题.

在第三次重新进入相​​机屏幕时捕获1或2个图像/视频时,图像是静态的,不会更新.视图停留在最后捕获的任何内容的最后一帧.

如果按下捕获按钮,则图像/视频会突然更新并捕获相机指向的内容.从那时起,选择器对于另一个正常行为是好的.此外,从相机胶卷中选择一张照片/视频似乎可以使所有内容再次显示另一张照片/视频.最后,当屏幕没有响应并且用户选择拍照时,视图将缩小为视图内的小矩形.控制器的设置如下:

    private void SourceChosen(EventHandler captureEvent, int buttonIndex, string[] mediaTypes)
    {
        var picker = ConfigurePicker(mediaTypes, captureEvent);

        if (CameraAvailable && buttonIndex == 0)
        {
            picker.SourceType = UIImagePickerControllerSourceType.Camera;
            picker.CameraDevice = UIImagePickerControllerCameraDevice.Rear;
            this.NavigationController.PresentViewController(picker, true, () => { });
        }

        if ((!CameraAvailable && buttonIndex == 0) || (CameraAvailable && buttonIndex == 1))
        {
            picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
            this.NavigationController.PresentViewController(picker, false, () => { });
        }
    }

    private UIImagePickerController ConfigurePicker(string[] mediaTypes, EventHandler captureEvent)
    {
        var mediaPicker = new UIImagePickerController();
        mediaPicker.FinishedPickingMedia += captureEvent;
        mediaPicker.Canceled += (sender, args) => mediaPicker.DismissViewController(true, () => { });
        mediaPicker.SetBarDefaults();
        mediaPicker.MediaTypes = mediaTypes;
        return mediaPicker;
    }

captureEvent的示例如下:

    void PhotoChosen(object sender, UIImagePickerMediaPickedEventArgs e)
    {
        UIImage item = e.OriginalImage;
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), "png");
        string path = Path.Combine(IosConstants.UserPersonalFolder, fileName);
        NSData imageData = item.AsPNG();
        CopyData(imageData, path, fileName, ViewModel.Images, ((UIImagePickerController)sender));
    }

    private void CopyData(NSData imageData, string path, string fileName, List collectionToAddTo, UIImagePickerController picker)
    {
        byte[] imageBytes = new byte[imageData.Length];
        System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, imageBytes, 0, Convert.ToInt32(imageData.Length));
        File.WriteAllBytes(path, imageBytes);

        AssociatedItem item = new AssociatedItem
        {
            StorageKey = fileName
        };

        collectionToAddTo.Add(item);
        picker.DismissViewController(true, ReloadTables);
    }

目前您可以看到我们没有持有对选择器的引用,但是我们尝试了这个代码的变体,我们存储了对选择器的引用并在CopyData方法之后处理它,我们添加了picker.Release() ; 在copydata之后和处置之前(导致随后的选择器在显示时崩溃应用程序)以及主题上几乎所有其他变体.

有谁知道为什么会发生这种情况以及如何解决这个问题?我的假设是我们可能在内存上运行不足但是每次都没有处理它/只创建一个实例并且从图片到视频改变它的模式有任何影响,我们总是看到相同的行为.

编辑

感谢Kento以及下面的回答,我们需要的是让所有工作按预期工作的内容如下:

public class PickerDelegate : UIImagePickerControllerDelegate
{
    private readonly Action _captureEvent;

    public PickerDelegate(Action captureEvent)
    {
        _captureEvent = captureEvent;
    }

    public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info)
    {
        _captureEvent(picker, info);
    }
}

然后得到一个图像

    void PhotoChosen(UIImagePickerController picker, NSDictionary info)
    {
        UIImage item = (UIImage)info.ObjectForKey(UIImagePickerController.OriginalImage);
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), "png");
        string path = Path.Combine(IosConstants.UserPersonalFolder, fileName);
        NSData imageData = item.AsPNG();
        CopyData(imageData, path, fileName, ViewModel.Images, picker);
    }

或者获取视频

    void VideoChosen(UIImagePickerController picker, NSDictionary info)
    {
        var videoURL = (NSUrl)info.ObjectForKey(UIImagePickerController.MediaURL);
        NSData videoData = NSData.FromUrl(videoURL);
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), "mov");
        string path = Path.Combine(IosConstants.UserPersonalFolder, fileName);
        CopyData(videoData, path, fileName, ViewModel.Videos, picker);
    }

Kento.. 5

我有同样的问题.

这里的帖子没有标记为答案,但确实为我解决了这个问题:https: //stackoverflow.com/a/20035698/2514318

我猜这是使用FinishedPickingMedia事件时MonoTouch的错误.我已经读过使用UIImagePickerController存在泄漏(无论使用obj c还是Mono)所以我更喜欢保留实例并重新使用它.如果你每次都重新创建它,我会建议处理前一个实例.

如果这是一个错误,Xamarin的任何人都可以权衡吗?

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有