【问题标题】:How to retrieve Image/Gif file loaded to SimpleDraweeView - Android如何检索加载到 SimpleDraweeView - Android 的图像/Gif 文件
【发布时间】:2019-07-17 11:31:50
【问题描述】:

所以基本上我想访问加载到SimpleDraweeView 中的图像或 Gif 的文件/ByteArray。当 Fresco 从 url 下载图像时,我想将该图像保存在我的数据库中以供将来访问(以帮助减少数据使用),因为这些图像不会更改。这样,下次我想将图像加载到SimpleDraweeView 时,我会加载本地媒体,无需从 url 再次下载。

在向Fresco.newDraweeControllerBuilder 添加侦听器后,我尝试了几种方法,onFinalImageSet 上我是:

1- 尝试从 Fresco 使用的缓存中访问图像/gif 的 File 以获取它的 ByteArray,但是,我总是从 ImagePipelineFactory 获得 hasKey() = False

val imageRequest = ImageRequest.fromUri(mediaUrl)
val cacheKey = DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(imageRequest, null)
if(ImagePipelineFactory.getInstance().mainFileCache.hasKey(cacheKey)) {
    val resource = ImagePipelineFactory.getInstance().mainFileCache.getResource(cacheKey) 
    val file = (resource as FileBinaryResource).file
}else if (ImagePipelineFactory.getInstance().smallImageFileCache.hasKey(cacheKey)){
    val resource = ImagePipelineFactory.getInstance().mainFileCache.getResource(cacheKey) 
    val file = (resource as FileBinaryResource).file
}

2- 尝试从imageInfo(作为CloseableStaticBitmap)或animatable(作为CloseableAnimateImage)获取位图但是如果我想将动画转换为CloseableAnimateImage,我会得到一个编译错误“未解决的参考:CloseableAnimateImage”。然后的想法是从位图中获取 ByteArray 并保存它。不过,我真的很想得到(1)的方法。

关于如何获取缓存文件的任何想法?提前谢谢!

【问题讨论】:

  • 你应该使用库 Glide/Picasso
  • @LakhwinderSingh fab... 代码建议?
  • 对于 Glide 还是 Picasso?
  • 我们试试毕加索

标签: android file fresco


【解决方案1】:

使用滑翔:

GlideApp.with(context)
            .load(url)
            .into(new SimpleTarget<Drawable>() {
                @Override
                public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                    // save image here
                }
            });

使用毕加索:

Target target = new Target() {
      @Override
      public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            // save image here
      }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {}

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {}
    };

    Picasso.with(this).load(url).into(target);

【讨论】:

  • 嗨!非常感谢您的回答 - 他们看起来很有希望!它们也适用于 gif 吗?
  • 嗨,我确定 Glide 可以,我不确定 Picasso。
  • 出于某种原因,在 Picasso 中未调用 onBitmapLoaded。但是当我关闭并打开应用程序时,使用 Picasso.LoadedFrom.DISK 调用相同的 url 并返回位图。为什么第一次没有调用 onBitmapLoaded ?仅供参考 onBitmapFailed 也没有被调用。
  • 是的,这可能会发生,它的解释可以在:stackoverflow.com/questions/24180805/… 或这里github.com/square/picasso/issues/352 找到。如果你仍然不能让它工作,我会建议切换到 Glide,如果它不是太麻烦的话。
【解决方案2】:

在 gradle 中添加依赖

implementation 'com.squareup.picasso:picasso:2.71828'

然后你在哪里显示图像

Picasso.get().load("URL").into(target);

为毕加索添加一个目标

Target target = new Target() {
      @Override
      public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            imageView.setBitmap(bitmap)
            //You can do whatever you want to do with bitmap

      }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
}

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
}};

【讨论】:

  • 我认为您没有理解我的问题。我需要将 Picasso 加载的文件(或 Glide 或 SimpleDraweeView 的内部实现或其他)存储在他们的缓存中。我能够在视图中加载图像 - 这不是问题。我想要的是访问缓存的文件。
  • “我想将该图像保存在我的数据库中以供将来访问”。此外,毕加索会在他们决定时删除文件(由于性能/未使用图像节省内存等),因此下次我想加载图像时,它必须再次下载。加上我需要对文件做的其他事情,因此我需要文件。
  • 已更新答案,请查收
  • 查看我对亚历克斯回答的评论。
【解决方案3】:

最后,直到有人可以用SimpleDraweeView 回答如何做到这一点,我决定同时选择 Glide。 Picasso 不是一个选项,因为它不支持 gif,这是我的问题中的要求之一。此外,我想继续在ImageView 中显示加载的图像,因此我不想将into 更改为自定义目标。

因此使用 Glide 的解决方案如下:

首先,我们尝试通过tryToGetFromMyDatabase在我的数据库中找到下载的媒体。如果找到它,我们将继续使用 Glide 简单地加载 ByteArray。如果我们没有找到保存在数据库中的媒体,tryToGetFromMyDatabase 将返回 null,因此我们继续使用 Glide 加载 url 并在 Glide 完成下载媒体时收听。完成后,我们从 Glide 的缓存中检索文件并将ByteArray 保存在我的数据库中。

这种方法的代码如下:

val url: String = "http://myUrl"
val mediaByteArray: ByteArray? = tryToGetMediaFromMyDatabase(url)
val myImageView: ImageView = findViewById(R.id.image_view)

if(mediaByteArray == null){
    //We don't have the media saved in our database se we download from url and on response save it in database
    var builder = if(isGif){
            Glide.with(context)
            .asGif()
            .load(mediaUrl)
            .addListener(object: RequestListener<GifDrawable> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<GifDrawable>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: GifDrawable?, model: Any?, target: Target<GifDrawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    onMediaLoaded(mediaUrl)
                    return false
                }
            })

        }else{
            Glide.with(context)
            .asBitmap()
            .load(mediaUrl)
            .addListener(object: RequestListener<Bitmap>{
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    onMediaLoaded(mediaUrl)
                    return false
                }

            })
        }

builder.into(myImageView)

}else{
    //We have the media saved in database so we just load it without downloading it from the url
    var builder = if(isGif){
            Glide.with(context).asGif()
        }else{
            Glide.with(context).asBitmap()
        }
    builder.load(mediaByteArray).into(myImageView)
}

我的onMediaLoaded(url: String) 执行以下操作以从 Glide 缓存中获取文件并将其保存到我的数据库中:

Thread(Runnable {
    val imageBytes = Glide.with(context)
            .asFile()
            .load(url)
            .submit()
            .get()
            .readBytes()
    saveIntoDatabase(url, imageBytes)
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多