在 Xamarin.Forms 中序列化 ImageSource
Posted
技术标签:
【中文标题】在 Xamarin.Forms 中序列化 ImageSource【英文标题】:Serialize ImageSource in Xamarin.Forms 【发布时间】:2021-03-31 06:19:39 【问题描述】:我正在尝试序列化一个成员为ImageSource
类型的类。
班级是:
public class AppInfo
public string Name get; set;
public ImageSource Icon get; set;
public bool Is90Hz get; set;
我得到这样的类的数据:
private static IList<AppInfo> GetAppInfos()
var localAppInfo = new List<AppInfo>();
var allAppsRaw = DependencyService.Get<IGetAllApps>().GetApps();
var pm = android.App.Application.Context.PackageManager;
if (pm == null)
return null;
foreach (var info in allAppsRaw)
var bitmap = DependencyService.Get<IGetAllApps>().DrawableToBitmap(info.LoadIcon(pm));
byte[] bitmapData;
using (var stream = new MemoryStream())
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
var imageSource = ImageSource.FromStream(() => new MemoryStream(bitmapData, 0, bitmapData.Length));
localAppInfo.Add(new AppInfo Name = info.LoadLabel(pm), Icon = imageSource, Is90Hz = true );
return localAppInfo;
问题在于 System.Text.Json 无法序列化该类型。我来回搜索如何将其转换为字节数组或 Base64 字符串,但我有点迷路了。
我将[JsonConverter(typeof(ImageSourceConverter))]
添加到成员并声明我的转换器类如下:
public class ImageSourceConverter : JsonConverter<ImageSource>
public override ImageSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
public override void Write(Utf8JsonWriter writer, ImageSource value, JsonSerializerOptions options)
但我现在有点迷失了......只是无法弄清楚读写方法的逻辑。
*编辑: 最终目标是展示它,目前的做法:
<ListView Grid.Column="3" x:Name="AppsView" CachingStrategy="RecycleElement" Margin="10,10,10,10">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" CompressedLayout.IsHeadless="true">
<Image Source="Binding Icon, Mode=TwoWay" WidthRequest="40" HeightRequest="40" HorizontalOptions="StartAndExpand"/>
<Label Text="Binding Name, Mode=TwoWay" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
<Switch IsToggled="Binding Is90Hz, Mode=TwoWay" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
【问题讨论】:
我认为没有任何简单的方法可以做到这一点。 ImageSource 并非旨在公开其基础数据。您最好在 AppInfo 类中存储文件路径、url 或 byte[]。 【参考方案1】:Xamarin.Forms 使用 Image 视图在页面上显示图像。它有几个重要的属性:
Source - 一个 ImageSource 实例,可以是 File、Uri 或 Resource,用于设置要显示的图像。
ImageSource可以使用静态方法为每种类型的图像源获取实例:
FromFile
- 需要一个可以在每个平台上解析的文件名或文件路径。
FromUri
- 需要一个 Uri 对象,例如。新的 Uri("http://....") .
FromResource
- 需要资源标识符来嵌入应用程序或 .NET Standard 库项目中的图像文件,并带有
构建操作:EmbeddedResource。
FromStream
- 需要一个提供图像数据的流。
所以你可以尝试绑定流:
改变
public ImageSource Icon get; set;
到
public Stream Icon get; set;
然后添加流:
var imageSource = new MemoryStream(bitmapData, 0, bitmapData.Length);
localAppInfo.Add(new AppInfo Name = info.LoadLabel(pm), Icon = imageSource, Is90Hz = true );
在您的 xaml 中:
<Image>
<Image.Source>
<StreamImageSource Stream="Binding Icon"
</Image.Source>
</Image>
【讨论】:
【参考方案2】:谢谢,我最终用转换器做了类似的事情。 在我的 xaml 中:
<ContentPage.Resources>
<ResourceDictionary>
<api:ByteArrayToImageConverter x:Key="Bti"/>
</ResourceDictionary>
</ContentPage.Resources>
<Image Source="Binding Icon, Converter=StaticResource Bti, Mode=Default" WidthRequest="37" HeightRequest="37" HorizontalOptions="StartAndExpand"/>
转换器类:
public class ByteArrayToImageConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
if (value == null)
return null;
var imageAsBytes = (byte[])value;
return ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
throw new NotImplementedException();
我只是将照片保存为byte[]
:
var bitmap = DependencyService.Get<IGetAllApps>().DrawableToBitmap(info.LoadIcon(pm));
byte[] bitmapData;
using (var stream = new MemoryStream())
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
localAppInfo.Add(new AppInfo
Name = info.LoadLabel(pm), PackageName = info.PackageName, Icon = bitmapData, Is90Hz = true);
【讨论】:
以上是关于在 Xamarin.Forms 中序列化 ImageSource的主要内容,如果未能解决你的问题,请参考以下文章
无法反序列化当前 JSON 对象 xamarin.forms
Xamarin.Forms DependencyService 始终返回 null
如何在我的 Xamarin Forms 应用程序上本地保存一些用户数据?
Xamarin.Forms:如何在 Xamarin.Forms 跨平台项目中开发具有蓝牙连接的应用程序?
如何使用 Xamarin.Forms.Maps(无 Xamarin.Forms.GoogleMaps)在地图中应用样式或更改颜色