question

Amasu-3175 avatar image
0 Votes"
Amasu-3175 asked guineapig-dance commented

How to save and retrieve Image using SQLite in Xamarin Forms

Hi Xamarin Team,

I am in the process of finishing and app using Xamarin Forms, but the last process that I need is to make a Profile Page, everything works, the only thing I need is to save and retrieve the imagen so the user can see it using sqlite,

My Model Class is:

[Table("Perfil")]
    public class Profile
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string Name{ get; set; }
        public string Email { get; set; }
        public ImageSource ProfilePic { get; set; }
    }


Hope you can help me with and example or a process of how to make this

Regards

Thanks.

dotnet-xamarindotnet-sqlite
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered guineapig-dance commented

Hello,​

Welcome to our Microsoft Q&A platform!

First of all, please change the type of ProfilePic from ImageSource to string.

[Table("Perfil")]
    public class Profile
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string ProfilePic { get; set; }
    }


Then you have two ways to store image to SQLite DB.

First way (recommand this way): You can store Image FilePath to SQLite DB.

For example, when you Xamarin.Essentials: Media Picker to picker a image or take a photo, you can get the file path. I click the Picker Button in my demo, to execute the Button_Clicked_1 method. I can get the PhotoPath, then I click the save Button to execute Button_Clicked, to save the Profile to SQLite DB.

private void Button_Clicked(object sender, EventArgs e)
        {
           
            if (PhotoPath!=null)
            {
                var profile=new Profile();

                profile.Email = "test@111";
                profile.Name = "test1";
                profile.ProfilePic = PhotoPath;
                App.Database.SaveNoteAsync(profile);              
            }
          
        }

        private async void Button_Clicked_1(object sender, EventArgs e)
        {
          await PickerPhotoAsync();
        }

        string PhotoPath = null;
        async Task PickerPhotoAsync()
        {
            try
            {
                var photo = await MediaPicker.PickPhotoAsync();
                await LoadPhotoAsync(photo);
                Console.WriteLine($"CapturePhotoAsync COMPLETED: {PhotoPath}");
            }
            catch (FeatureNotSupportedException fnsEx)
            {
                // Feature is not supported on the device
            }
            catch (PermissionException pEx)
            {
                // Permissions not granted
            }
            catch (Exception ex)
            {
                Console.WriteLine($"CapturePhotoAsync THREW: {ex.Message}");
            }
        }

        async Task LoadPhotoAsync(FileResult photo)
        {
            // canceled
            if (photo == null)
            {
                PhotoPath = null;
                return;
            }
            // save the file into local storage
            var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
            using (Stream stream = await photo.OpenReadAsync())
            using (var newStream = File.OpenWrite(newFile))
            {
                await stream.CopyToAsync(newStream);
                
            }               
            PhotoPath = newFile;
        }
    }


Second way:

If you do not want to save filePath to the SQLite DB, you can read the Image to byte[], then convert to it Base64 string. save Base64 string to the SQLite DB, when you need to show the image. read Base64 string from DB, then convert Base64 string to Stream, then you can display it.

//Convert Byte[] to Base64, you can store Base64String to the Sqlite DB
                var result = GetFileBytes(PhotoPath);
                string imageBase64 = Convert.ToBase64String(result);
                //Convert Base64string to Stream.

                byte[] bytes = System.Convert.FromBase64String(imageBase64);
                testImage.Source = ImageSource.FromStream(() => new MemoryStream(bytes));



Here is my demo running screenshot.

121757-image.png

For testing, you can refer to my NoteDatabase.cs as well.

using SQLite;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace XFsqliteDemo
{
    public class NoteDatabase
    {
        readonly SQLiteAsyncConnection database;

        public NoteDatabase(string dbPath)
        {
            database = new SQLiteAsyncConnection(dbPath);
            database.CreateTableAsync<Profile>().Wait();
        }

        public Task<List<Profile>> GetNotesAsync()
        {
            //Get all notes.
            return database.Table<Profile>().ToListAsync();
        }

        public Task<Profile> GetNoteAsync(int id)
        {
            // Get a specific note.
            return database.Table<Profile>()
                            .Where(i => i.Id == id)
                            .FirstOrDefaultAsync();
        }

        public Task<int> SaveNoteAsync(Profile note)
        {
            if (note.Id != 0)
            {
                // Update an existing note.
                return database.UpdateAsync(note);
            }
            else
            {
                // Save a new note.
                return database.InsertAsync(note);
            }
        }

        public Task<int> DeleteNoteAsync(Profile note)
        {
            // Delete a note.
            return database.DeleteAsync(note);
        }
    }
}


Best Regards,

Leon Lu



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.




image.png (32.8 KiB)
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@LeonLu-MSFT Thanks so much for this example, it works perfect,

You are awesome

Thanks
Regards.

0 Votes 0 ·

Hello, I didnt understood this line

var result = GetFileBytes(PhotoPath);

how I use GetFileBytes?

0 Votes 0 ·
guineapig-dance avatar image guineapig-dance viniciusnascimentodemoraes-7640 ·

You can use this converter to get your bytes where photo is a MediaFile in this example. The key is get hold of your stream of your media object:

using (Stream photoStream = photo.GetStream())
{
// convert image to bytes
MemoryStream ms = new MemoryStream();
photoStream.CopyTo(ms);
byte[] bytes = ms.ToArray();

}

0 Votes 0 ·