Xamarin Forms сохранение изображения в базе данных sqlite - PullRequest
0 голосов
/ 18 февраля 2020

Как сохранить полученное изображение непосредственно в базе данных sqlite (sqlite- net -pcl)?

Вот мой код, но его можно сохранить только во «Внутреннем хранилище» телефона.

private async void TakePhotoButton_Clicked(object sender, EventArgs e)
{
    try
    {
        await CrossMedia.Current.Initialize();
        if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
        {
            await DisplayAlert("No Camera", "No Camera Available", "OK");
            return;
        }

        var file = await CrossMedia.Current.TakePhotoAsync(
        new StoreCameraMediaOptions
        {
            SaveToAlbum = true,
            //Directory = "Sample",
            //Name = "Test.jpg"
        });

        if (file == null)
            return;

        PathLabel.Text = file.AlbumPath;
        MainImage.Source = ImageSource.FromStream(() =>
        {
            var stream = file.GetStream();
            file.Dispose();
            return stream;

        });
    }
    catch (Exception ex)
    {
        await DisplayAlert("error", ex.ToString(), "OK");
    }

}

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Вы должны преобразовать поток в массив байтов, чтобы сохранить их в sqlite.

public byte[] GetImageStreamAsBytes(Stream input)
{
  var buffer = new byte[16*1024];
  using (MemoryStream ms = new MemoryStream())
  {
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
                ms.Write(buffer, 0, read);
    }
      return ms.ToArray();
   }
}
var imgDate = GetImageStreamAsBytes(file.GetStream());
1 голос
/ 18 февраля 2020

Относительно опции SaveToAlbum

Это приведет к сохранению 2 фотографий для фотографии. Один в вашей личной папке и один в опубликованном каталоге c, который показан. Значение будет возвращено на AlbumPath. ( Источник )

Если вам действительно не нужна фотография в рулоне камеры, нет необходимости использовать SaveToAlbum.

В любом случае, файл все еще сохраняется в изолированной программной среде ваших приложений (часть хранилища устройств, зарезервированной исключительно для вашего приложения), и вы можете получить путь с помощью file.Path.

Сказав это, легко получить двоичные данные, представляющие ваше изображение

await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
    await DisplayAlert("No Camera", "No Camera Available", "OK");
    return;
}

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions());

if (file == null)
    return;

var imageData = File.ReadAllBytes(file.Path);

Очевидно ( см. Здесь и здесь ) это возможно хранить двоичные данные ( BLOB s) в базе данных SQLite. Самая простая мыслимая модель для хранения изображения в базе данных будет выглядеть примерно так:

class Image
{
    [PrimaryKey, AutoIncrement]
    public int ID { get; set; }

    public byte[] Data { get; set; }
}

Если предположить, что _imageRepository - это абстракция репозитория, в которой вы сохраняете изображения, данные можно сохранить как

// ...
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions());

if (file == null)
    return;

var imageData = File.ReadAllBytes(file.Path);

_imageRepository.Add(new Image()
                         {
                             Data = imageData
                         });

Позже, чтобы отобразить изображение, вы можете получить Image из хранилища и использовать свойство Data, например, передав его в MemoryStream (, если вам нужно поток)

// example: Loading by ID, loading all images is conceivable, too
var image = _imageRepository.LoadImage(id);
ImageControl.ImageSource = ImageSource.FromStream(() => new MemoryStream(image.Data));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...