Glide - Сохранить GIF в файл - PullRequest
0 голосов
/ 03 июня 2018

Sidenote - хотя некоторые из моих примеров приведены на Kotlin, ответы на Java или Kotlin полезны.

Я создаю GIF-клавиатуру с использованием Commit Content API .Для этого мне нужно иметь возможность создавать .gif файлов.

Я использую Glide для получения изображений из Интернета и отображения их в списке внутри recyclerview.

Для каждого изображения, загружаемого Glide, мне нужно создать объект File с данными этого изображения.

Я вижу два метода, которые могут выполнить эту задачу.

1] Создатьслушатель, который переопределяет onResourceReady вот так.Проблема с этим методом заключается в том, что я не знаю, как преобразовать GifDrawable в .gif файл, потому что все сообщения о переполнении стека говорят о том, как преобразовать 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, взятый из поста Glide - скачайте и измените размер GIF в файл , может выглядеть так.Проблема с этим кодом состоит в том, что

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();

Может кто-нибудь помочь мне улучшить любой из этих двух методов или предложить новый способ преобразования GIF в файлс Glide?

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Обновление @ Решение 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)

Затем я получаюGifDrawable из ImageView и запишите его в 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 какпоэтому перед записью в файл:

val newGifDrawable = ((holder.imageView.drawable).constantState.newDrawable().mutate()) as GifDrawable
0 голосов
/ 03 июня 2018

Если вам не нужно сохранять все картинки в одном определенном месте и / или называть их, я предлагаю вам просто использовать картинки, которые Glide автоматически кеширует для вас.

Итак, во-первых,в вашем методе 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();
...