【问题标题】:How to show Base64 image string in ListView in Xamarin Forms?如何在 Xamarin Forms 的 ListView 中显示 Base64 图像字符串?
【发布时间】:2018-03-29 09:30:48
【问题描述】:

我对 Xamarin、MVVM 和跨平台应用程序开发(Android、iOS、UWP)非常陌生。我正在使用 Realm 以 Base64 格式存储/显示图像。我已成功存储图像 base64 字符串,但 在 ListView 中显示图像时遇到困难

ImageModel.cs

namespace RealmTest.Models
{
    public class ImageModel : RealmObject
    {
        [PrimaryKey]
        public string ImageId { get; set; } = Guid.NewGuid().ToString();

        public string ImageName { get; set; }

        public string ImageBase64 { get; set; }

        public string ImageCaseHistory { get; set; }

    }
}

BaseViewModel.cs

namespace RealmTest.ViewModels
{
    public class BaseViewModel : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

RealmImageViewModel.cs

namespace RealmTest.ViewModels
{
    public class RealmImageViewModel : BaseViewModel
    {
        private ObservableCollection<ImageModel> imagesList;
        public ObservableCollection<ImageModel> ImagesList
        {
            get
            {
                return imagesList;
            }
            set
            {
                imagesList = value;
            }
        }

        public RealmImageViewModel()
        {
            Realm context = Realm.GetInstance();
            ImagesList = new ObservableCollection<ImageModel>(context.All<ImageModel>());

            Debug.WriteLine($"ImagesList ==>" + ImagesList.Count());
        }
    }
}

HomePage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RealmTest.Views.HomePage"
             Title="Home">
    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Add"
                     Icon="ic_add_black.png"/>
    </ContentPage.ToolbarItems>

    <ContentPage.Content>

        <ListView ItemsSource="{Binding ImagesList}"
                  HasUnevenRows="True"
                  BackgroundColor="#f5f5f5">

            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>

                        <Grid BackgroundColor="White"
                              Margin="4">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>


                            <Label Grid.Row="0"
                                   Text="{Binding ImageName}"
                                   FontSize="Medium"
                                   Margin="4"
                                   FontAttributes="Bold" />

                            <Image Source="{Binding ImageBase64}" 
                                   HeightRequest="150"
                                   Grid.Row="1"
                                   />

                            <StackLayout Orientation="Horizontal"
                                         Grid.Row="2"
                                         Margin="4"
                                         Padding="2">

                                <Label Text="{Binding ImageCaseHistory}"
                                       FontSize="Small" />

                                <Label Text="{Binding ImageName}"
                                       FontSize="Small" />

                            </StackLayout>
                        </Grid>

                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </ContentPage.Content>

</ContentPage>

HomePage.cs

namespace RealmTest.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class HomePage : ContentPage
    {
        public HomePage()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            BindingContext = new RealmImageViewModel();

            /**
            var image = Xamarin.Forms.ImageSource.FromStream(
                () => new MemoryStream(Convert.FromBase64String(base64)));
            **/
        }
    }
}

到目前为止,我已经了解了关于我的问题/查询的两件事 -

  1. 我可以将base64 字符串显示为图像格式,例如 -

    var image = Xamarin.Forms.ImageSource.FromStream( () => new MemoryStream(Convert.FromBase64String(base64)));

  2. 我在 SO 上阅读了 this answer 并了解到可以创建一些 ConverterBase64ImageSource,但我无法理解它,如何制作和实现它。

我仍然无法找到在 ListView 中显示所有图像(在我的 Realm 数据库中为 Base64 字符串格式)的方法。

【问题讨论】:

  • 从 Realm 获取图像时,将图像保存在本地可能会更有效,然后显示本地副本
  • @Jason - 当我开始时,将图像存储在本地是最初的想法,但不知何故,我觉得将图像和相关信息同步/上传到在线数据库变得越来越困难。使用base64,我可以使用单一功能上传所有信息,并且可以在多个设备上同步数据。您是否仍然建议使用在本地存储图像?
  • 我是说当你从 Realm 检索 base64 图像时,你还应该将其作为图像缓存在本地,而不是尝试动态解码流,这似乎很昂贵
  • @Jason - 我的错。对不起。在我发表评论后,我明白了你的意思。是的,这似乎是更好的方法。我会努力解决它。感谢您的建议。
  • 图片源不能直接设置base64字符串,需要使用转换器,将base64转换为图片源。

标签: image listview xamarin xamarin.forms base64


【解决方案1】:

我找到了一些不同的方法来做到这一点,我在我的 localDB (SQLite) 中保存了一个 base64 文件。

这是在模型中:

//这里我们将base64转换为ImageSource

     string foto;
    [JsonProperty(PropertyName = "Foto")]
    public string Foto
    {
        get { return foto; }
        set
        {
            foto = value;
            OnPropertyChanged("Foto");

            FOTO = Xamarin.Forms.ImageSource.FromStream(
                () => new MemoryStream(Convert.FromBase64String(foto)));
        }
    }
    private Xamarin.Forms.ImageSource _foto;
    [Ignore]//The localdb don't support the ImageSource
    public Xamarin.Forms.ImageSource FOTO
    {
        get { return _foto; }
        set
        {
            _foto = value;
            OnPropertyChanged("FOTO");
        }
    }

在我的例子中,我使用这个类来转换文件:

public class FilesHelper
    {
        public static byte[] ReadFully(Stream input)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                input.CopyTo(ms);
                return ms.ToArray();
            }
        }
    }

这里我们将图片转换成base64文件保存在localDB中:

 byte[] imageArray = null;
            String image = "";
            if (this.file != null)
            {
                imageArray = FilesHelper.ReadFully(this.file.GetStream());

                image = Convert.ToBase64String(imageArray);
            }

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 2016-06-15
    • 2016-10-31
    • 2021-10-09
    • 1970-01-01
    • 2011-09-10
    • 2019-02-13
    相关资源
    最近更新 更多