看似簡單的功能,實施起來倒是有着一堆大坑。json
按着基本功能來寫吧數組
1.選擇圖片並顯示到Image控件中網絡
2.圖片序列化爲byte數組以及反序列化dom
3.本地存儲與讀取async
1.選擇圖片:ide
邏輯就是使用FileOpenPicker選擇一個圖片文件後,將該文件從StorageFile對象轉化成能夠賦值給Image.Source的ImageSource類的對象。ui
(這裏須要注意的是WriteableBitmap,BitmapImage,SoftwareBitmapSource均可以賦值給Image.Source,你賦值給Image.Source的是什麼對象,你就只能用as符把Image.Source轉化成什麼對象。 好比:你使用WriteableBitmap賦值給Image.Source,那麼你後面只能用 var t = imageSource as WriteableBitmap, 你若是使用var t = imageSource as BitmapImage的話編譯器不會報錯,可是t的值最後會是null)this
1.1 選取圖片文件並實例化爲WriteableBitmap對象spa
private async void ChoosePhoto() { FileOpenPicker fileOpenPicker = new FileOpenPicker(); fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; fileOpenPicker.FileTypeFilter.Add(".jpg"); fileOpenPicker.FileTypeFilter.Add(".png"); fileOpenPicker.ViewMode = PickerViewMode.Thumbnail; StorageFile imgFile_tmp = await fileOpenPicker.PickSingleFileAsync(); if (imgFile_tmp == null) { return; } else { this.imgFile = imgFile_tmp; using (IRandomAccessStream stream = await imgFile.OpenAsync(FileAccessMode.Read)) { var srcImage = new WriteableBitmap(50,50); await srcImage.SetSourceAsync(stream); Image_Thumbnail.Source = srcImage; } } }
1.2 選取圖片文件並實例化爲BitmapImage對象code
private async void ChoosePhoto() { FileOpenPicker fileOpenPicker = new FileOpenPicker(); fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; fileOpenPicker.FileTypeFilter.Add(".jpg"); fileOpenPicker.FileTypeFilter.Add(".png"); fileOpenPicker.ViewMode = PickerViewMode.Thumbnail; StorageFile imgFile_tmp = await fileOpenPicker.PickSingleFileAsync(); if (imgFile_tmp == null) { return; } else { this.imgFile = imgFile_tmp; using (IRandomAccessStream stream = await imgFile.OpenAsync(FileAccessMode.Read)) { var srcImage = new BitmapImage(); await srcImage.SetSourceAsync(stream); Image_Thumbnail.Source = srcImage; } } }
1.3 選取圖片實例化爲SoftwareBitmapSource對象
private async void ChoosePhoto() { FileOpenPicker fileOpenPicker = new FileOpenPicker(); fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; fileOpenPicker.FileTypeFilter.Add(".jpg"); fileOpenPicker.FileTypeFilter.Add(".png"); fileOpenPicker.ViewMode = PickerViewMode.Thumbnail; StorageFile imgFile_tmp = await fileOpenPicker.PickSingleFileAsync(); if (imgFile_tmp == null) { return; } else { SoftwareBitmap softwareBitmap; this.imgFile = imgFile_tmp; using (IRandomAccessStream stream = await imgFile.OpenAsync(FileAccessMode.Read)) { // Create the decoder from the stream BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); // Get the SoftwareBitmap representation of the file softwareBitmap = await decoder.GetSoftwareBitmapAsync(); } if (softwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 || softwareBitmap.BitmapAlphaMode == BitmapAlphaMode.Straight) { softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied); } var source = new SoftwareBitmapSource(); await source.SetBitmapAsync(softwareBitmap); // Set the source of the Image control Image_Thumbnail.Source = source; } }
2.圖片序列化爲byte數組以及反序列化
2.1 WriteableBitmap對象(Image.Source賦值的時候使用的是WriteableBitmap)序列化爲byte數組
public static async Task<byte[]> SaveToBytesAsync(ImageSource imageSource) { byte[] imageBuffer; var localFolder = ApplicationData.Current.TemporaryFolder; var file = await localFolder.CreateFileAsync("temp.jpg", CreationCollisionOption.GenerateUniqueName); using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None)) { WriteableBitmap bitmap = imageSource as WriteableBitmap; var stream = bitmap.PixelBuffer.AsStream(); byte[] buffer = new byte[stream.Length]; await stream.ReadAsync(buffer, 0, buffer.Length); BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, buffer); await encoder.FlushAsync(); var imageStream = ras.AsStream(); imageStream.Seek(0, SeekOrigin.Begin); imageBuffer = new byte[imageStream.Length]; var re = await imageStream.ReadAsync(imageBuffer, 0, imageBuffer.Length); } await file.DeleteAsync(StorageDeleteOption.Default); return imageBuffer; }
2.2Byte數組反序列化爲ImageSource(WriteableBitmap)
public static async Task<ImageSource> SaveToImageSource(byte[] imageBuffer) { ImageSource imageSource = null; try { using (MemoryStream stream = new MemoryStream(imageBuffer)) { var ras = stream.AsRandomAccessStream(); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, ras); var provider = await decoder.GetPixelDataAsync(); byte[] buffer = provider.DetachPixelData(); WriteableBitmap bitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight); await bitmap.PixelBuffer.AsStream().WriteAsync(buffer, 0, buffer.Length); imageSource = bitmap; } } catch (Exception ex) { } return imageSource; }
2.3 BitmapImage對象序列化爲byte數組
須要注意的是這裏所調用的BitmspImage對象,必須是使用BitmapImage(uri)方法實例化出來的BitmapImage對象,所以下列方法主要用於實現對網絡圖片的序列化與反序列化。
若是使用從FileOpenPicker選取出來圖片文件實例化出來的BitmapImage對象的話,該對象的UriSource屬性爲空,故下列方法沒法實現。
RandomAccessStreamReference random = RandomAccessStreamReference.CreateFromUri(himage.UriSource); IRandomAccessStreamWithContentType streamWithContent = await random.OpenReadAsync(); byte[] buffer = new byte[streamWithContent.Size]; await streamWithContent.ReadAsync(buffer.AsBuffer(), (uint)streamWithContent.Size, InputStreamOptions.None);
2.4 byte數組反序列化爲BitmapImage對象
BitmapImage image = new BitmapImage(); using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream()) { await stream.WriteAsync(obj.ImgArray.AsBuffer()); stream.Seek(0); await image.SetSourceAsync(stream); }
3.本地存儲與讀取
(須要注意的是:StorageFile這類的存儲操做貌似只容許存一些簡單的數據類型,因此個人解決方法就是把自定義的類的對象裏的圖片轉化爲byte數組,而後再將自定義類的對象的List轉化成json字符串存進文件,讀取文件的時候再讀出這些Json字符串並反序列化爲我須要的類型)
3.1 存儲數據
public static async Task SaveData(string filename, T data) { try { StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream raStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { using (IOutputStream outStream = raStream.GetOutputStreamAt(0)) { var json = JsonConvert.SerializeObject(data); DataContractSerializer serializer = new DataContractSerializer(typeof(string)); serializer.WriteObject(outStream.AsStreamForWrite(), json); var t =JsonConvert.DeserializeObject<T>(json); await outStream.FlushAsync(); } } } catch (Exception exc) { throw exc; } }
3.2 加載數據
public static async System.Threading.Tasks.Task<List<ShowInfo>> LoadData(string filename) { try { if (ApplicationData.Current.LocalFolder.TryGetItemAsync(filename) != null) { StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(filename); using (IInputStream inStream = await file.OpenSequentialReadAsync()) { DataContractSerializer serializer = new DataContractSerializer(typeof(string)); var json = (string)serializer.ReadObject(inStream.AsStreamForRead()); var data = JsonConvert.DeserializeObject<List<ShowInfo>>(json); return data; } } else { return new List<ShowInfo>(); } } catch (FileNotFoundException ex) { throw ex; } catch (Exception ex) { throw ex; } }