将位图图像转换为Json序列化的UWP。

将位图图像转换为Json序列化的UWP。,json,serialization,uwp,bitmapimage,Json,Serialization,Uwp,Bitmapimage,我有一个类(MyClass),我使用 public class MyClass { public string Name { get; set;} public BitmapImage image { get; set;} } private ObservableCollection<MyClass> _myClass; private const string fileName = "myclass.json"; public DataSource() { _myC

我有一个类(MyClass),我使用

public class MyClass
{
  public string Name { get; set;}
  public BitmapImage image { get; set;}
}

private ObservableCollection<MyClass> _myClass;

private const string fileName = "myclass.json";

public DataSource()
{
 _myClass = new ObservableCollection<MyClass>();
}

public async Task<ObservableCollection<MyClass>> GetMyClass()
{
  await ensureDataLoaded();
  return _myClass;
}

private async Task ensureDataLoaded()
{
  if(_myClass.Count == 0;)
     await GetMyClassDataAsync();
}

private async Task GetMyClassDataAsync()
{
   if(_myClass.Count != 0)
       return;

var jsonSerializer = new DataContractJsonSerializer(typeof(ObservableCollection<MyClass>));

try
 {
  using(var stream = away ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(fileName))
   {
   _myClass = (ObservableCollection<MyClass>) jsonSerializer.ReadObject(stream);
   }
 }
catch
 {
  _myClass = new ObservableCollection<MyClasss>();
 }
}

public async void AddMyClass(MyClass myClass)
{
   _myClass.Add(myClass);
   await SaveMyClassDataAsync();
}

public async void DeleteMyClass(MyClass myClass)
{
   _myClass.Remove(myClass);
   await SaveMyClassDataAsync();
}

private async Task SaveMyClassDataAsync()
{
   var jsonSerializer = new DataContractJsonSerializer(typeof(ObservableCollection<MyClass>));
   using (var stream = await ApplicationData.Current.LocatlFolder.OpenStreamForWriteAsync(fileName, 
   CreationCollisionOption.ReplaceExisting))
 {
   jsonSerializer.WriteObject(stream, _myClass);
 }
}
公共类MyClass
{
公共字符串名称{get;set;}
公共位图图像{get;set;}
}
私有可观测集合myClass;
private const string fileName=“myclass.json”;
公共数据源()
{
_myClass=新的ObservableCollection();
}
公共异步任务GetMyClass()
{
等待确保加载();
返回我的类;
}
私有异步任务ensureDataLoaded()
{
如果(_myClass.Count==0;)
等待GetMyClassDataAsync();
}
专用异步任务GetMyClassDataAsync()
{
如果(_myClass.Count!=0)
返回;
var jsonSerializer=新的数据契约jsonSerializer(typeof(ObservableCollection));
尝试
{
使用(var stream=away ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(文件名))
{
_myClass=(ObservableCollection)jsonSerializer.ReadObject(流);
}
}
抓住
{
_myClass=新的ObservableCollection();
}
}
公共异步void AddMyClass(MyClass MyClass)
{
_添加(myClass);
等待SaveMyClassDataAsync();
}
公共异步void DeleteMyClass(MyClass MyClass)
{
_myClass.Remove(myClass);
等待SaveMyClassDataAsync();
}
专用异步任务SaveMyClassDataAsync()
{
var jsonSerializer=新的数据契约jsonSerializer(typeof(ObservableCollection));
使用(var stream=wait ApplicationData.Current.LocatlFolder.OpenStreamForWriteAsync)(文件名,
CreationCollisionOption.ReplaceExisting)
{
jsonSerializer.WriteObject(流,_myClass);
}
}
当我向类中添加bitmapImage时,它无法序列化

我读过有关将位图图像转换为字符串或字节数组的内容,但我无法理解代码

有人知道如何将位图图像转换为可以序列化的格式吗

奖金

将其转换为json格式后。我如何将其转换回

更多奖金


如果我有一个链接到XAML中每个MyClass对象的所有图像的列表视图,那么我需要做什么特殊的事情,以便MyClass保存一个图像&一个序列化的图像,这样我可以用json保存图像,但也可以用图像从MyClass绑定到XAML中的图像?

在UWP中,BitmapImage用于将UI用作图像源。它不是读/写对象。因此,我的建议是自行序列化/反序列化图像数据(此处为字节数组),并使用这些数据为绑定发布ImageBitmap属性

[JsonObject(MemberSerialization.OptIn)]
public class MyClass
{
    private BitmapImage _Image;
    [JsonProperty]
    public string Name { get; set; }
    public BitmapImage Image
    {
        get
        {
            if (ImageBytes == null)
                return null;
            if (_Image == null)
                _Image = new BitmapImage();
            using (var stream = new InMemoryRandomAccessStream())
            {
                stream.WriteAsync(ImageBytes.AsBuffer()).Completed = (i, j) => {
                    stream.Seek(0);
                    _Image.SetSource(stream);
                };
            }
            return _Image;
        }
    }
    [JsonProperty]
    public byte[] ImageBytes { get; set; }
}

如果你有一个图像的URI,故事会有点不同;)

在setter中异步等待?您可能正在尝试从另一个线程访问UI线程。尝试使用调度程序。RunAsync(Windows.UI.Core.CoreDispatcherPriority.High,()=>{XAMLimage.Source=\u myClass.Image;});当我说设置图像时,我道歉。我的意思是从PickSingleFileAsync流将映像设置为_myClass.image,在我访问XAMLimage.Source之前,尝试将映像设置为_myClass.image时出错。在我的示例中,您没有设置映像属性,而是设置ImageBytes属性,序列化/反序列化的ImageBytes属性。PickSingleFileAsync将为您提供一个StorageFile,您必须从那里获取字节数组,并将其设置为的ImageBytes属性可能重复