Glide - 将 GIF 保存到文件
Glide - Save GIF to File
旁注 - 尽管我的一些示例是使用 Kotlin 编写的,但使用 Java 或 Kotlin 编写的答案很有帮助。
我正在使用 Commit Content API 创建 GIF 键盘。为此,我需要能够创建 .gif
个文件。
我正在使用 Glide 从互联网上获取图像并将它们显示在 recyclerview
.
中的列表中
对于 Glide 下载的每个图像,我必须使用该图像的数据创建一个 File
对象。
我看到有两种方法可以完成这个 objective。
1] 像这样创建一个覆盖 onResourceReady
的侦听器。这种方法的问题是我不知道如何将 GifDrawable
转换为 .gif
文件,因为所有 Stack Overflow post 都在谈论如何将 Drawable
转换为] 到文件:
Glide.with(context)
.asGif()
.load(items[position])
.listener(object : RequestListener<GifDrawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<GifDrawable>?, isFirstResource: Boolean): Boolean {
Log.d("VED-APP","Glide Load Failed")
return false
}
override fun onResourceReady(resource: GifDrawable?, model: Any?, target: Target<GifDrawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
//I need code to convert the GifDrawable to a File
return false
}
})
.into(holder.imageView)
2] 将图像加载到 ByteArray
或类似的东西。示例 Java 代码取自 post ,可能如下所示。这段代码的问题是
A] .into(width,height)
已弃用
B]没有.toBytes
方法
C] 我不想指定 GIF 的尺寸 - 我只想使用原始尺寸。 (或者,至少,我想保留纵横比)
byte[] bytes = Glide.with(context)
.load(items[position])
.asGif()
.toBytes()
.into(250, 250)
.get();
file = new File(fileName);
FileOutputStream fileWriter = new FileOutputStream(file);
fileWriter.write(bytes);
fileWriter.flush();
fileWriter.close();
有人可以帮助我改进这两种方法中的任何一种,或者建议一种使用 Glide 将 GIF 转换为文件的新方法吗?
如果您不必将所有的 gif 文件都保存在一个特定的位置and/or必须给 gif 文件命名,我建议您使用 Glide 自动为您缓存的 gif 文件即可。
因此,首先,在您的 OnBindViewHolder 方法中,只需正常将 gif 加载到图像视图即可:
Glide.with(this)
.load(items[position])
.apply(new RequestOptions()
// This is to cache all versions of the gif, whether low-res or original size
.diskCacheStrategy(DiskCacheStrategy.ALL))
.into(holder.imageView);
并使用此方法在任何你想要的地方获取 uri:
Glide.with(this)
// Actually it won't download another time if the file has been cached
.download(items[position])
.listener(new RequestListener<File>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<File> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(File resource, Object model, Target<File> target, DataSource dataSource, boolean isFirstResource) {
//Use this uri for the Commit Content API
Uri uri = Uri.fromFile(resource);
return false;
}
})
.submit();
更新 @Nhật Tôn 的解决方案可能更好,如果您只需要内容提交的 URI API。
不知道@Nhật Tôn 的解决方案是否有效。但是,这是我现在使用的解决方案,它基于他们的解决方案。我的解决方案是在 Kotlin 中,但它可以很容易地转换为 Java.
首先,我使用以下代码将图像加载到 ImageView
中:
//items[position] is a string that represents a URL
Glide.with(context)
.load(items[position])
.into(holder.imageView)
然后我从 ImageView
中获取 GifDrawable
并将其写入 File
对象。
val byteBuffer = (holder.imageView.drawable as GifDrawable).buffer
val gifFile = File(localDirectory, "test.gif")
val output = FileOutputStream(gifFile)
val bytes = ByteArray(byteBuffer.capacity())
(byteBuffer.duplicate().clear() as ByteBuffer).get(bytes)
output.write(bytes, 0 ,bytes.size)
output.close()
此解决方案的一个潜在问题是 GifDrawable
在写入文件时可能会被修改。
解决此问题的方法是在将 GifDrawable
写入文件之前克隆 GifDrawable
:
val newGifDrawable = ((holder.imageView.drawable).constantState.newDrawable().mutate()) as GifDrawable
旁注 - 尽管我的一些示例是使用 Kotlin 编写的,但使用 Java 或 Kotlin 编写的答案很有帮助。
我正在使用 Commit Content API 创建 GIF 键盘。为此,我需要能够创建 .gif
个文件。
我正在使用 Glide 从互联网上获取图像并将它们显示在 recyclerview
.
对于 Glide 下载的每个图像,我必须使用该图像的数据创建一个 File
对象。
我看到有两种方法可以完成这个 objective。
1] 像这样创建一个覆盖 onResourceReady
的侦听器。这种方法的问题是我不知道如何将 GifDrawable
转换为 .gif
文件,因为所有 Stack Overflow post 都在谈论如何将 Drawable
转换为] 到文件:
Glide.with(context)
.asGif()
.load(items[position])
.listener(object : RequestListener<GifDrawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<GifDrawable>?, isFirstResource: Boolean): Boolean {
Log.d("VED-APP","Glide Load Failed")
return false
}
override fun onResourceReady(resource: GifDrawable?, model: Any?, target: Target<GifDrawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
//I need code to convert the GifDrawable to a File
return false
}
})
.into(holder.imageView)
2] 将图像加载到 ByteArray
或类似的东西。示例 Java 代码取自 post
A] .into(width,height)
已弃用
B]没有.toBytes
方法
C] 我不想指定 GIF 的尺寸 - 我只想使用原始尺寸。 (或者,至少,我想保留纵横比)
byte[] bytes = Glide.with(context)
.load(items[position])
.asGif()
.toBytes()
.into(250, 250)
.get();
file = new File(fileName);
FileOutputStream fileWriter = new FileOutputStream(file);
fileWriter.write(bytes);
fileWriter.flush();
fileWriter.close();
有人可以帮助我改进这两种方法中的任何一种,或者建议一种使用 Glide 将 GIF 转换为文件的新方法吗?
如果您不必将所有的 gif 文件都保存在一个特定的位置and/or必须给 gif 文件命名,我建议您使用 Glide 自动为您缓存的 gif 文件即可。
因此,首先,在您的 OnBindViewHolder 方法中,只需正常将 gif 加载到图像视图即可:
Glide.with(this)
.load(items[position])
.apply(new RequestOptions()
// This is to cache all versions of the gif, whether low-res or original size
.diskCacheStrategy(DiskCacheStrategy.ALL))
.into(holder.imageView);
并使用此方法在任何你想要的地方获取 uri:
Glide.with(this)
// Actually it won't download another time if the file has been cached
.download(items[position])
.listener(new RequestListener<File>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<File> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(File resource, Object model, Target<File> target, DataSource dataSource, boolean isFirstResource) {
//Use this uri for the Commit Content API
Uri uri = Uri.fromFile(resource);
return false;
}
})
.submit();
更新 @Nhật Tôn 的解决方案可能更好,如果您只需要内容提交的 URI API。
不知道@Nhật Tôn 的解决方案是否有效。但是,这是我现在使用的解决方案,它基于他们的解决方案。我的解决方案是在 Kotlin 中,但它可以很容易地转换为 Java.
首先,我使用以下代码将图像加载到 ImageView
中:
//items[position] is a string that represents a URL
Glide.with(context)
.load(items[position])
.into(holder.imageView)
然后我从 ImageView
中获取 GifDrawable
并将其写入 File
对象。
val byteBuffer = (holder.imageView.drawable as GifDrawable).buffer
val gifFile = File(localDirectory, "test.gif")
val output = FileOutputStream(gifFile)
val bytes = ByteArray(byteBuffer.capacity())
(byteBuffer.duplicate().clear() as ByteBuffer).get(bytes)
output.write(bytes, 0 ,bytes.size)
output.close()
此解决方案的一个潜在问题是 GifDrawable
在写入文件时可能会被修改。
解决此问题的方法是在将 GifDrawable
写入文件之前克隆 GifDrawable
:
val newGifDrawable = ((holder.imageView.drawable).constantState.newDrawable().mutate()) as GifDrawable