如何从图库中选择图像并保存到 xamarin 中的 sql 数据库

Posted

技术标签:

【中文标题】如何从图库中选择图像并保存到 xamarin 中的 sql 数据库【英文标题】:How to select image from gallery and save to sql database in xamarin 【发布时间】:2021-04-08 21:53:05 【问题描述】:

我已使用 Xamarin Media Plugin 进行图像上传,我想将该图像保存在 Sqlite 中并从 Sqlite 中检索回来。我该怎么做?

存储:将 Image 位图转换为 Base64String 并存储到 SQLite。

public static string Base64Encode(string plainText) 
  var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
  return System.Convert.ToBase64String(plainTextBytes);

检索:获取 Base64String 并再次将其转换为位图。

public static string Base64Decode(string base64EncodedData) 
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);

以及 -- 如果是这样,我在哪里实现这些 Base64Encode?​​strong>

using Plugin.Media;
using Plugin.Media.Abstractions;
using System;
using Xamarin.Forms;
using SQLite;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace PersonListData

    public class Person
       
        [PrimaryKey, AutoIncrement]
        public int IdSis  get; set; 
        public string NamePerson  get; set; 
        public byte[] PersonImg  get; set; 
    
    
    async void SaveOnClik(object sender, EventArgs e)
    
        var person = (Person)BindingContext;
        await App.Database.SavePersonAsync(person);
        await Navigation.PopAsync();
    

    async void PickPhotos(object sender, EventArgs e)
    
        if (CrossMedia.Current.IsPickPhotoSupported)
        
            var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
            
                PhotoSize = PhotoSize.Medium,
            );
            if (file == null)
                return;

            image.Source = ImageSource.FromStream(() =>
            
                var stream = file.GetStream();
                file.Dispose();
                return stream;
            );          
        
        else
        
            await DisplayAlert("Image error", ":( Hcant do thid.", "Ok");
            return;
        

    
    readonly SQLiteAsyncConnection _database;
    public DataPerson(string dbPath)
    
        _database = new SQLiteAsyncConnection(dbPath);
        _database.CreateTableAsync<Person>().Wait();
    
    public Task<List<Person>> GetPersonListAsync()
    
        return _database.Table<Person>().ToListAsync();
    
    public Task<Person> GetPersonAsync(int id)
    
        return _database.Table<Person>()
        .Where(i => i.IdSis == id)
        .FirstOrDefaultAsync();
    
    public Task<int> SavePersonAsync(Person person)
    
        if (person.IdSis != 0)
        
            return _database.UpdateAsync(person);
        
        else
        
            return _database.InsertAsync(person);
        
    
    public Task<int> DeletePersonAsync(Person person)
    
        return _database.DeleteAsync(person);
    

我对这个位置感到困惑

【问题讨论】:

你真的需要将实际图像存储在 sqlite 中吗?将图像存储为文件并将路径或 id 放入数据库中通常会更有效。 如果有更好更轻的东西,何不试一试。有这方面的参考吗? 在我看来是这样的安排: - 从画廊加载图像 - 保存/删除:以字符串格式,例如链接到数据库。 - 可以重新加载图片链接到设备界面。想成为那样,但我缺乏理解 C# 的经验 我的建议是将图像数据存储为文件,并将路径或文件名作为字符串存储在数据库中。实际上将图像数据存储在数据库中会增加复杂性而几乎没有好处。 如果您保留一长串人员,最终会是这样。数据库肯定膨胀:)。那我从哪里开始把文件名写入数据库,上面的代码会不会全部改? 【参考方案1】:

您可以尝试将图像路径保存到 sqlite 数据库中。

在模型中创建一个路径属性。

 public class Person
   
    [PrimaryKey, AutoIncrement]
    public int IdSis  get; set; 
    public string NamePerson  get; set; 
    public string Path get; set; 
    public byte[] PersonImg  get; set; 

然后将字符串保存到数据库中。

   public Task<int> SaveItemAsync(Person item)
    
        if (item.ID != 0)
        
            return Database.UpdateAsync(item);
        
        else
        
            return Database.InsertAsync(item);
        
    

您可以查看下面的链接,其中包含有关如何将字符串保存到 sqlite 数据库的代码示例。 https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/data/databases

如果你还想把byte[]存入sqlite数据库,你需要把stream转换成byte[]。请检查如何将图像从流转换为字节的方式。 How to save an image in SQLite in Xamarin Forms?

【讨论】:

感谢您的好评。通常我会将条目存储在数据库中。只是放置一些与Base64 集成的代码我仍然很困惑。在这个问题的时间范围内,我试图找到其他替代方案,例如通过获取字符串文件位置并保存到数据库而无需更改为byte []。好吧,希望这个问题得到解决:) 这个问题有什么更新吗?文件路径适合你吗? 文件路径原地不动,我的重点是转换图像文件并将其加载到数据库中【参考方案2】:

我不再考虑用 base64 保存照片

在c#中

using Plugin.Media;
....

async void GetPersonImage(object sender, EventArgs e)
    
        if (!CrossMedia.Current.IsPickPhotoSupported)
        
            await DisplayAlert("Foto tidak didukung", ":( Hak akses dibatasi.", "Oke deh ..");
            return;
        
        var file = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
        
            PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
    
        );
    
        if (file == null)
            return;
    
        string path = file.Path;
        FtSiswa.Text = path; //this label hide
    
        await DisplayAlert("Foto disimpan di: ", file.Path, "OK");
    
        KameraFotos.Source = ImageSource.FromStream(() =>
        
            var stream = file.GetStream();
            file.Dispose();
            return stream;
        );
    

在xml中

.... &lt;Image x:Name="KameraFotos" BackgroundColor="Bisque" Grid.Column="2" Grid.RowSpan="2" Aspect="AspectFit"&gt; &lt;Image.Source&gt; &lt;FileImageSource File="Binding PersonImg" /&gt; &lt;/Image.Source&gt; &lt;TapGestureRecognizer Tapped="GetPersonImage" NumberOfTapsRequired="1" /&gt; &lt;/Image.GestureRecognizers&gt; &lt;/Image&gt; ....

我觉得把图片保存在数据库中记录的文件的路径和地址中效率更高

【讨论】:

以上是关于如何从图库中选择图像并保存到 xamarin 中的 sql 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何从图库(Android Studio)中选择并保存图像?

从图库中选择图像并保存以备将来使用

Flutter 如何将图像文件保存到图库中的新文件夹?

如何调整 xamarin.forms 中的图像大小?

如何调整 xamarin.forms 中的图像大小?

如何从 SwiftUI 中的图库中选择图像