2 votes

Comment sauvegarder une image dans SQLite dans Xamarin Forms ?

Je dispose des deux méthodes suivantes, qui permettent de prendre des photos à partir d'un appareil photo et de choisir des photos dans une bibliothèque. Ces deux méthodes sont similaires car, à la fin de chacune d'entre elles, j'obtiens un message d'erreur ImageSource de retour de la Stream et je le passe à une autre page qui a une ImageSource liaison prête à être mise en place. Ces deux méthodes fonctionnent parfaitement. L'étape suivante consiste maintenant à sauvegarder l'image dans SQLite afin de pouvoir afficher les images dans un ListView par la suite. Ma question pour les XamGods (Xamarin Pros =), quelle est la meilleure façon de sauvegarder une image dans SQLite en 2019 ? J'ai été dans les forums pendant des heures et je n'ai toujours pas une vision tunnel sur ce que je veux faire. Je peux soit

  • Convertit Stream en un tableau d'octets à sauvegarder dans Sqlite.
  • Convertit ImageSource en un tableau d'octets (désordonné/buggy).
  • Récupérer l'image sélectionnée/prise et la convertir en un tableau d'octets dans SQLite.

Je suis désolé si ma question est générale, mais Xamarin ne fournit pas de solution claire sur la façon de sauvegarder des images dans SQLite et vous ne pouvez trouver que des bribes de solutions dans les forums listés ci-dessous.

Merci d'avance !

    private async Task OnAddPhotoFromCameraSelected()
    {
        Console.WriteLine("OnAddPhotoFromCameraSelected");

        var photo = await Plugin.Media.CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions() { });
        var stream = photo.GetStream();
        photo.Dispose();
        if (stream != null)
        {
            ImageSource cameraPhotoImage = ImageSource.FromStream(() => stream);
            var parms = new NavigationParameters();
            parms.Add("image", cameraPhotoImage);
            var result = await NavigationService.NavigateAsync("/AddInspectionPhotoPage?", parameters: parms);

            if (!result.Success)
            {
                throw result.Exception;
            }
        }
    }

    private async Task OnAddPhotoFromLibrarySelected()
    {
        Console.WriteLine("OnAddPhotoFromLibrarySelected");
        Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
        if (stream != null)
        {
            ImageSource selectedImage = ImageSource.FromStream(() => stream);

            var parms = new NavigationParameters();
            parms.Add("image", selectedImage);
            parms.Add("stream", stream);
            var result = await NavigationService.NavigateAsync("/AddInspectionPhotoPage?", parameters: parms);

            if (!result.Success)
            {
                throw result.Exception;
            }
        }
    }

4voto

Cherry Bu Points 873

Comme Jason l'a dit, vous pouvez sauvegarder le chemin de l'image dans la base de données sqlite, mais si vous voulez toujours sauvegarder un byte[] dans la base de données sqlite, vous devez d'abord convertir le flux en byte[] :

 private byte[] GetImageBytes(Stream stream)
    {
        byte[] ImageBytes;
        using (var memoryStream = new System.IO.MemoryStream())
        {              
            stream.CopyTo(memoryStream);             
            ImageBytes = memoryStream.ToArray();
        }
        return ImageBytes;
    }

Ensuite, charger des byte[] depuis sqlite, en les convertissant en flux.

 public Stream BytesToStream(byte[] bytes)
    {
        Stream stream = new MemoryStream(bytes);
        return stream;
    }

Pour un simple échantillon, vous pouvez jeter un coup d'œil : Insérer un byte[] dans sqlite :

 private void insertdata()
    {
        var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "sqlite1.db3");
        using (var con = new SQLiteConnection(path))
        {
            Image image = new Image();
            image.Content = ConvertStreamtoByte();
            var result = con.Insert(image);

            sl.Children.Add(new Label() { Text = result > 0 ? "insert successful insert" : "fail insert" });
        }
    }

Chargement de l'image depuis sqlite :

 private void getdata()
    {
        var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "sqlite1.db3");
        using (var con = new SQLiteConnection(path))
        {
            var image= con.Query<Image>("SELECT content FROM Image ;").FirstOrDefault();

            if(image!=null)
            {
                byte[] b = image.Content;
                Stream ms = new MemoryStream(b);
                image1.Source = ImageSource.FromStream(() => ms);                   
            }

        }
    }

Modèle :

public class Image
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string FileName { get; set; }   
    public byte[] Content { get; set; }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X