Save UIImage to personal folder and then load it via UIImage.FromFile
-
13-06-2021 - |
Domanda
I´ve done a picture selector via UIImagePickerController. Because of the memory issues this one has I want to save the selected image to disc and if needed load it from filepath. But I can´t manage to get it working.
If i bind the original image directly it is displayed with no problems.
File.Exists in the code returns true but image in the last line is null if watched in debugger.. Thank you very much for your help!
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);
Update
This is the code that works for me:
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;
}
Soluzione
byte[] tempImage = new byte[data.Length];
File.WriteAllBytes(pathTempImage, tempImage);
You're not copying the image data
to your allocated array before saving it. That result in a large empty file that is not a valid image.
Try using one of the NSData.Save
overloads, like:
NSError error;
data.Save (pathTempImage, NSDataWritingOptions.FileProtectionNone, out error);
That will allow you to avoid allocating the byte[]
array.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow