【问题标题】:How to Download Image From Url and Save It to a Local SQLite Database如何从 URL 下载图像并将其保存到本地 SQLite 数据库
【发布时间】:2017-05-11 06:53:12
【问题描述】:

在 Xamarin 中,如何从 URL 下载图像?

然后,如何将图像保存到设备上的本地 SQLite 数据库中?

我的 Xamarin.Forms 应用当前遵循 Xamarin Documentation 来使用 ImageImageSource 属性的 URL,这可以正常工作。但是,我注意到每次应用程序启动时,它都会通过网络重新下载此图像。我宁愿从 URL 下载一次图像并将其保存到本地设备;此方法将为用户节省电池和数据使用量。

【问题讨论】:

    标签: c# sqlite xamarin xamarin.forms


    【解决方案1】:

    说明

    为此,我们将使用 HttpClient 从 URL 下载图像为 byte[],然后将其保存到我们的本地 SQLite 数据库。

    示例应用

    Here is a sample app 使用 Xamarin.Forms 完成此操作。为了更好地理解,我建议从 GitHub 下载代码。

    示例代码

    从网址下载图片

    我们将使用HttpClient 将图像下载为byte[]。这将更容易将其存储在我们的 SQLite 数据库中。

        const int _downloadImageTimeoutInSeconds = 15;
        readonly HttpClient _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(_downloadImageTimeoutInSeconds) };
    
        async Task<byte[]> DownloadImageAsync(string imageUrl)
        {
            try
            {
                using (var httpResponse = await _httpClient.GetAsync(imageUrl))
                {
                    if (httpResponse.StatusCode == HttpStatusCode.OK)
                    {
                        return await httpResponse.Content.ReadAsByteArrayAsync();
                    }
                    else
                    {
                        //Url is Invalid
                        return null;
                    }
                }
             }
             catch (Exception e)
             {
                 //Handle Exception
                 return null;
             }
        }
    

    将模型保存到数据库

    将图像下载为byte[] 后,我们会将其存储在 SQLite 数据库中。

    我在下一节中添加了有关该模型的更多信息。

    public static async Task SaveDownloadedImage(DownloadedImageModel downloadedImage)
    {
        var databaseConnection = await GetDatabaseConnectionAsync();
        await databaseConnection.InsertOrReplaceAsync(downloadedImage);
    }
    

    型号

    在模型中,我创建了一个将图像存储为字符串的属性和一个将图像返回为Xamarin.Forms.ImageSource 的只读属性。

    public class DownloadedImageModel
    {
        [PrimaryKey]
        public string ImageUrl { get; set;}
    
        public byte[] DownloadedImageBlob { get; set; }
    
        public ImageSource DownloadedImageAsImageStreamFromBase64String
        {
            get
            {
                try
                {
                    if (DownloadedImageBlob == null)
                        return null;
    
                    var imageByteArray = DownloadedImageBlob;
    
                    return ImageSource.FromStream(() => new MemoryStream(imageByteArray));
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                    return null;
                }
            }
        }
    }
    

    【讨论】:

    • 无法将图像 byte[] 保存到 X* 下的 BLOB 列(与转换为 B64 相比)?
    • 嗨@Plutonix!我没有玩过这种方法。您是否有示例代码显示如何执行此操作?使用 blob 存储与 Base-64 字符串的优缺点是什么?
    • 在 Winforms 中,使用 NET 提供程序就像所有其他提供程序一样:cmd.Parameters.Add("@img", DbType.Binary).Value = imgBytes,其中后者是 byte[]。 B64 的缺点是它更长:编码 870 字节图像的 1140+ 字节字符串。此外,仍然在 winforms 中,提供程序可以向您返回一个 Image 对象,因此您不必对其进行解码。由于膨胀,保存图像而不是存档图像的路径通常是一个坏主意。 SQLite 可能更是如此
    • 好东西!我不知道字节大小的差异。您有在 Xamarin 中显示此内容的示例吗?我很想看看!
    • 不要在 using 语句中使用 HttpClient。将其视为共享资源并尽可能多地重用它。还要小心将大图像加载到内存中。最好将其保存到文件中,而只是让数据库指向路径。
    猜你喜欢
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    相关资源
    最近更新 更多