You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin中如何将选取的图片存入本地SQLite并在其他页面展示

实现方案

方案1:存储本地文件路径(推荐,无需手动处理Stream,性能最优)

这是符合你需求的优化方案,核心逻辑是把选中的图片复制到APP私有沙盒目录,数据库只存储文件的绝对路径,后续直接用路径绑定图片,不需要额外格式转换,数据库体积和查询速度都远优于存二进制的方案。

步骤1:修改Post模型类

新增字符串类型的图片路径字段即可:

public class Post
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Title { get; set; }
    public string Experience { get; set; }
    public string Location { get; set; }
    // 新增图片本地路径存储字段
    public string ImagePath { get; set; }
}

步骤2:媒体选择后存储图片到本地

拿到MediaPicker返回的FileResult后直接复制到本地目录,框架封装的复制方法不需要你手动操作Stream读写:

// 拍照/图库选图完成后的处理逻辑
private async void OnMediaSelected(FileResult result)
{
    if (result == null) return;

    // 生成唯一的本地存储路径,避免文件名重复
    var localPath = Path.Combine(FileSystem.AppDataDirectory, 
        $"{Guid.NewGuid()}{Path.GetExtension(result.FileName)}");
    
    // 直接复制文件到本地
    using (var sourceStream = await result.OpenReadAsync())
    using (var destStream = File.Create(localPath))
    {
        await sourceStream.CopyToAsync(destStream);
    }

    // 组装Post对象
    var newPost = new Post
    {
        Title = TitleEntry.Text,
        Experience = ExperienceEditor.Text,
        Location = LocationLabel.Text,
        ImagePath = localPath
    };

    // 调用你已有的SQLite插入逻辑即可
    await _db.InsertAsync(newPost);
}

步骤3:ListView绑定图片显示

Xamarin.Forms的Image控件原生支持本地文件路径作为Source,直接绑定即可,不需要额外转换:

<ListView ItemsSource="{Binding PostList}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal" Padding="10">
                    <Image Source="{Binding ImagePath}" WidthRequest="80" HeightRequest="80" Aspect="AspectFill"/>
                    <StackLayout Padding="10,0">
                        <Label Text="{Binding Title}" FontAttributes="Bold" FontSize="Medium"/>
                        <Label Text="{Binding Location}" FontSize="Small" TextColor="Gray"/>
                        <Label Text="{Binding Experience}" MaxLines="2" LineBreakMode="TailTruncation" FontSize="Small"/>
                    </StackLayout>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

方案2:直接存储二进制到SQLite

如果你确实需要把图片完整存在数据库中,不需要单独保留本地文件,按以下步骤实现:

步骤1:修改Post模型类

新增byte数组类型的字段,SQLite会自动映射为BLOB类型存储:

public class Post
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Title { get; set; }
    public string Experience { get; set; }
    public string Location { get; set; }
    // 存储图片二进制数据
    public byte[] ImageData { get; set; }
}

步骤2:图片转二进制入库

private async void OnMediaSelected(FileResult result)
{
    if (result == null) return;

    byte[] imageBytes;
    using (var stream = await result.OpenReadAsync())
    using (var memoryStream = new MemoryStream())
    {
        await stream.CopyToAsync(memoryStream);
        imageBytes = memoryStream.ToArray();
    }

    var newPost = new Post
    {
        Title = TitleEntry.Text,
        Experience = ExperienceEditor.Text,
        Location = LocationLabel.Text,
        ImageData = imageBytes
    };
    await _db.InsertAsync(newPost);
}

步骤3:绑定到ListView显示

需要新增一个值转换器,把byte数组转为ImageSource:
首先创建转换器类:

public class ByteArrayToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is byte[] bytes)
        {
            return ImageSource.FromStream(() => new MemoryStream(bytes));
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然后在XAML中注册转换器并使用:

<ContentPage.Resources>
    <local:ByteArrayToImageSourceConverter x:Key="ByteToImageConverter"/>
</ContentPage.Resources>

<!-- ListView的ItemTemplate中Image的绑定写法 -->
<Image Source="{Binding ImageData, Converter={StaticResource ByteToImageConverter}}" 
       WidthRequest="80" HeightRequest="80" Aspect="AspectFill"/>

注意事项

  • 优先选择方案1,存储路径的方式会让SQLite数据库体积比存二进制小30%以上,查询、加载速度都更快
  • 用方案1的话,删除Post记录时需要同步删除对应的本地图片,新增一行File.Delete(post.ImagePath)即可

内容的提问来源于stack exchange,提问作者Patrick89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:45:06