Introduction
In Previous Part1 article we can resolve memory issue with listbox images,but unfortunate there is an issue In Listpage.xaml ,Because listbox Ui loads little bit slow when there are more caprtured images.The reason is in MainPage i was storing whole caprured imagesbytes in isolated storage and readed it on Listpage.xaml,it is little bit more complex for loading UI when reading whole captrured imagebytes.
So that in this part i am going to introduce best solution is,Direclty reference the isostore image path instead of storing and reading whole image bytes using Coding4Fun Toolkit: Introducing SuperImage .
Building the Sample
To use SuperImage we have to download Coding4Fun Toolkit and need to reference in your page like this
XAML
xmlns:coding4Fun="clr-namespace:Coding4Fun.Toolkit.Controls;assembly=Coding4Fun.Toolkit.Controls"
Or you may directly installed it from nugget packages
Description
Actually in previous i tried to reference the image binding with isoStore image path like this way
XAML
<Image Source="isostore:/Shared/SaveImages/Image0.jpg" />
But unfortunate,it won't work with direct isostore image paths
and after doing a small R&D,i had found an amazing control from coding4fun toolkit is SuperImage ,which can supports both isostore (from Windows Phone) and ms-appx (from Windows Store) as urls for your ImageSource.
so that we can direclty bind image paths from isostore using SuperImage like this,
XAML
<coding4Fun:SuperImage Source="isostore:/Shared/ShavedImages?Image0.jpg" Width="120" Stretch="Uniform"/>
However we need to follow some few steps as below,
1)How to Save captured Images in Local Folder of windows phone
After capturing the image from camera/photo chooser ,we need to store local folder ,in my case"Shared/SavedImagesFiles"
C#
Stream cameraimgstream; public const string StoragePath = "Shared/SavedImagesFiles"; public static async Task SaveImageToLocalFolder(Stream imageStream, string filename, string folder = StoragePath) { var isf = IsolatedStorageFile.GetUserStoreForApplication(); if (!isf.DirectoryExists(StoragePath)) { isf.CreateDirectory(StoragePath); } var file = (folder == null ? filename : String.Format("{0}/{1}", folder, filename)); if (isf.FileExists(file)) isf.DeleteFile(file); using (var stream = isf.OpenFile(file, FileMode.Create, FileAccess.ReadWrite)) { BitmapImage bitmap = new BitmapImage(); bitmap.SetSource(imageStream); WriteableBitmap wb = new WriteableBitmap(bitmap); wb.SaveJpeg(stream, wb.PixelWidth, wb.PixelHeight, 0, 85); stream.Close(); //var ms = new MemoryStream(ImageBytes, false); //await ms.CopyToAsync(stream); } }
And to use above method ,we need to call like
C#
if (cameraimgstream != null) { await SaveImageToLocalFolder(cameraimgstream, "Image" + count.ToString(), StoragePath); }
2)Direclty Bind Listbox with The IsoStore Images using SuperImage
Afetr saving images to isolatedstoarge local folder,we need to reference them,and so as part in our viemodel we need to another class (SavedData.cs) member for storing isostore image
like ImagePath= string.Format("isostore:/{0}", file.ToString())
afetr that we need all imagepath to list
C#
var file = (StoragePath == null ? "Image" + count.ToString() : String.Format("{0}/{1}", StoragePath, "Image" + count.ToString())); prkdata.ImagePath = file.ToString(); parkinglistobj.Add(new SavedData { ID = count + 1, Address = "Image" + count.ToString(),ImagePath= string.Format("isostore:/{0}", file.ToString())});
Finally bind list
<coding4Fun:SuperImage Source="{Binding ImagePath}" Width="120"
Stretch="Uniform"/>
C#
ParkListBox.ItemsSource = parkinglistobj.OrderByDescending(i => i.ID).ToList();
I have 255 thumbnails to load on listbox through in SuperImage, its load successfully at first time, but when if i navigate it again, than it generates the same outOfmemory exception. so this approach is not working, Subu, please try to load more than 200 thumbnails of the images and navigate twice and thrice, if it will not work than your solution is feasible, i am looking for now some more alternate solution.
ReplyDelete