【问题标题】:Save UIImage to personal folder and then load it via UIImage.FromFile将 UIImage 保存到个人文件夹,然后通过 UIImage.FromFile 加载它
【发布时间】:2012-06-11 13:48:24
【问题描述】:

我已经通过 UIImagePickerController 完成了一个图片选择器。由于内存问题,我想将选定的图像保存到磁盘,如果需要,从文件路径加载它。但我无法让它工作。

如果我直接绑定原始图像,它显示没有问题。

代码中的File.Exists返回true,但如果在调试器中观看,最后一行中的图像为空。非常感谢您的帮助!

                    NSData data = originalImage.AsPNG();

                    string path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
                    string pathTempImage = Path.Combine(path, "tempImage.png");

                    byte[] tempImage = new byte[data.Length];

                    File.WriteAllBytes(pathTempImage, tempImage);

                    if(File.Exists(pathTempImage))
                    {
                        int i = 0;
                    }

                    UIImage image = UIImage.FromFile(pathTempImage);

更新

这是适合我的代码:

void HandleFinishedPickingMedia (object sender, UIImagePickerMediaPickedEventArgs e)
    {
        _view.DismissModalViewControllerAnimated (true);

        BackgroundWorker bw = new BackgroundWorker();

        bw.DoWork += delegate(object bwsender, DoWorkEventArgs e2) {
            // determine what was selected, video or image
            bool isImage = false;
            switch(e.Info[UIImagePickerController.MediaType].ToString()) {
                case "public.image":
                    Console.WriteLine("Image selected");
                    isImage = true;
                    break;
                case "public.video":
                    Console.WriteLine("Video selected");
                    break;
            }

            // get common info (shared between images and video)
            NSUrl referenceURL = e.Info[new NSString("UIImagePickerControllerReferenceUrl")] as NSUrl;
            if (referenceURL != null)
                Console.WriteLine("Url:"+referenceURL.ToString ());

            // if it was an image, get the other image info
            if(isImage) {
                // get the original image  
                originalImage = e.Info[UIImagePickerController.OriginalImage] as UIImage;
                if(originalImage != null) {
                    NSData data = originalImage.AsPNG();
                    _picture = new byte[data.Length];

                    ImageResizer resizer = new ImageResizer(originalImage);
                    resizer.RatioResize(200,200);

                    string path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
                    string pathTempImage = Path.Combine(path, "tempImage.png");
                    string filePath = Path.Combine(path, "OriginalImage.png");

                    NSData dataTempImage = resizer.ModifiedImage.AsPNG();
                    byte[] tempImage = new byte[dataTempImage.Length];

                    System.Runtime.InteropServices.Marshal.Copy(dataTempImage.Bytes,tempImage,0,Convert.ToInt32(tempImage.Length));

                    //OriginalImage
                    File.WriteAllBytes(filePath, _picture); 

                    //TempImag
                    File.WriteAllBytes(pathTempImage, tempImage);


                    UIImage image = UIImage.FromFile(pathTempImage);

                    _view.InvokeOnMainThread (delegate {
                        templateCell.BindDataToCell(appSelectPicture.Label, image);
                    });

                    _picture = null;
                }
            } else { // if it's a video
                // get video url
                NSUrl mediaURL = e.Info[UIImagePickerController.MediaURL] as NSUrl;
                if(mediaURL != null) {
                    Console.WriteLine(mediaURL.ToString());
                }
            }          
            // dismiss the picker
        };

        bw.RunWorkerAsync();

        bw.RunWorkerCompleted += HandleRunWorkerCompleted;
    }

【问题讨论】:

    标签: ios xamarin.ios uiimagepickercontroller fromfile


    【解决方案1】:
    byte[] tempImage = new byte[data.Length];
    File.WriteAllBytes(pathTempImage, tempImage);
    

    在保存之前,您不会将图像 data 复制到分配的数组中。这会导致一个大的空文件不是有效的图像。

    尝试使用NSData.Save 重载之一,例如:

    NSError error;
    data.Save (pathTempImage, NSDataWritingOptions.FileProtectionNone, out error);
    

    这样可以避免分配byte[] 数组。

    【讨论】:

    • 因为我无法使用 data.Save 我使用 System.Runtime.InteropServices.Marshal.Copy 来填充数组。如果您有更多信息我必须如何使用 NSData.Save,我将再次感谢您 :) 所以感谢您将我引向正确的方向!