Как использовать скольжение для загрузки изображения в растровое изображение?

Загрузить URL-адрес в ImageView с помощью Glide очень просто:

Glide
   .with(context)
   .load(getIntent().getData())
   .placeholder(R.drawable.ic_loading)
   .centerCrop()
   .into(imageView);

Мне интересно, могу ли я также загрузить в Bitmap? Я хотел бы загрузить необработанное растровое изображение, которым затем можно было бы управлять с помощью других инструментов. Я просмотрел код и не понимаю, как это сделать.


person JohnnyLambada    schedule 10.12.2014    source источник


Ответы (11)


Убедитесь, что вы используете последнюю версию.

implementation 'com.github.bumptech.glide:glide:4.10.0'

Котлин:

Glide.with(this)
        .asBitmap()
        .load(imagePath)
        .into(object : CustomTarget<Bitmap>(){
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                imageView.setImageBitmap(resource)
            }
            override fun onLoadCleared(placeholder: Drawable?) {
                // this is called when imageView is cleared on lifecycle call or for
                // some other reason.
                // if you are referencing the bitmap somewhere else too other than this imageView
                // clear it here as you can no longer have the bitmap
            }
        })

Размер растрового изображения:

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

into(object : CustomTarget<Bitmap>(1980, 1080)

Java:

Glide.with(this)
        .asBitmap()
        .load(path)
        .into(new CustomTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }

            @Override
            public void onLoadCleared(@Nullable Drawable placeholder) {
            }
        });

Старый ответ:

С compile 'com.github.bumptech.glide:glide:4.8.0' и ниже

Glide.with(this)
        .asBitmap()
        .load(path)
        .into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }
        });

Для compile 'com.github.bumptech.glide:glide:3.7.0' и ниже

Glide.with(this)
        .load(path)
        .asBitmap()
        .into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                imageView.setImageBitmap(resource);
            }
        });

Теперь вы можете увидеть предупреждение SimpleTarget is deprecated

Причина:

Основная цель отказа от SimpleTarget - предупредить вас о том, как он соблазняет вас нарушить контракт API Glide. В частности, он ничего не делает, чтобы заставить вас прекратить использование любого загруженного вами ресурса после очистки SimpleTarget, что может привести к сбоям и повреждению графики.

SimpleTarget по-прежнему можно использовать, если вы убедитесь, что не используете растровое изображение после очистки imageView.

person Max    schedule 23.01.2017
comment
Я использую Glide 4.0 и не могу найти .asBitmap () - person Chris Nevill; 24.08.2017
comment
Будьте осторожны, вы должны указать предельный размер изображения для масштабирования, иначе есть вероятность, что изображение может быть больше, чем может обрабатывать OpenGL (приблизительно 4000 * 4000), и его нельзя будет загрузить. Пример: новый SimpleTarget ‹Bitmap› (512 512) - person Hoang Nguyen Huu; 13.09.2017
comment
Должен вызываться из основного потока, иначе выдается исключение! - person Jemshit Iskenderov; 14.02.2018
comment
Для синхронных вызовов используйте Glide.with (this) .asBitmap (). Load (pictureUrl) .submit (100, 100) .get (). Это может быть полезно, если вы хотите добавить значок в уведомление через .setLargeIcon (растровое изображение) - person Yazon2006; 12.06.2018
comment
@Max эта работа для меня в реализации 'com.github.bumptech.glide: glide: 3.6.1' - person Bipin Bharti; 04.08.2018
comment
Итак, как мне получить обратный вызов об ошибке? например, какой обратный вызов вызывается, если изображение не загружается. - person theapache64; 21.05.2019
comment
@Nux убедитесь, что у вас последняя версия 4.9.0 - person Max; 11.06.2019
comment
.asBitmap() следует поставить после with(this), если проблема не решена. - person Alston; 13.09.2019
comment
Это отлично сработало и для Glide версии 4.11.0. Но так ли это асинхронно? - person Istiak Morsalin; 14.03.2020
comment
Это мне очень помогает ... работает как шарм. Также использование apply (new RequestOptions (). Format (DecodeFormat.PREFER_ARGB_8888)) помогает мне поддерживать лучшее качество без потери памяти ... - person Mahbubur Rahman Khan; 24.03.2020
comment
Большое спасибо, макс. Это прекрасно работает. Ты спас мне день. - person Dinith Rukshan Kumara; 29.03.2020
comment
Glide.with(application).asBitmap().load(pictureUrl).circleCrop().submit().get() отлично работает для значка уведомления в дополнение к предложению @ Yazon2006 - person lasec0203; 19.09.2020

Я недостаточно знаком с Glide, но похоже, что если вы знаете целевой размер, вы можете использовать что-то вроде этого:

Bitmap theBitmap = Glide.
        with(this).
        load("http://....").
        asBitmap().
        into(100, 100). // Width and height
        get();

Похоже, вы можете пройти -1,-1 и получить полноразмерное изображение (основано исключительно на тестах, не вижу его в документации).

Примечание. into(int,int) возвращает FutureTarget<Bitmap>, поэтому вам нужно заключить это в блок try-catch, охватывающий ExecutionException и InterruptedException. Вот более полный, протестированный и работающий пример реализации:

class SomeActivity extends Activity {

    private Bitmap theBitmap = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // onCreate stuff ...
        final ImageView image = (ImageView) findViewById(R.id.imageView);

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Looper.prepare();
                try {
                    theBitmap = Glide.
                        with(SomeActivity.this).
                        load("https://www.google.es/images/srpr/logo11w.png").
                        asBitmap().
                        into(-1,-1).
                        get();
                 } catch (final ExecutionException e) {
                     Log.e(TAG, e.getMessage());
                 } catch (final InterruptedException e) {
                     Log.e(TAG, e.getMessage());
                 }
                 return null;
            }
            @Override
            protected void onPostExecute(Void dummy) {
                if (null != theBitmap) {
                    // The full bitmap should be available here
                    image.setImageBitmap(theBitmap);
                    Log.d(TAG, "Image loaded");
                };
            }
        }.execute();
    }
}

Следуя предложению Monkeyless в комментарии ниже (и , похоже, это тоже официальный способ), вы можете использовать SimpleTarget, опционально в сочетании с override(int,int), чтобы значительно упростить код. Однако в этом случае необходимо указать точный размер (все, что меньше 1, не принимается):

Glide
    .with(getApplicationContext())
    .load("https://www.google.es/images/srpr/logo11w.png")
    .asBitmap()
    .into(new SimpleTarget<Bitmap>(100,100) {
        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
            image.setImageBitmap(resource); // Possibly runOnUiThread()
        }
    });

как предлагает @hennry , если вам нужно то же изображение, используйте new SimpleTarget<Bitmap>()

person outlyer    schedule 10.12.2014
comment
Когда я попробовал это, я получил эту ошибку: `java.util.concurrent.ExecutionException: java.lang.NullPointerException: попытка чтения из поля 'int android.graphics.Bitmap $ Config.nativeInt' для ссылки на нулевой объект в com.bumptech.glide.request.RequestFutureTarget.doGet (RequestFutureTarget.java:208) ` - person JohnnyLambada; 10.12.2014
comment
@JohnnyLambada Похоже на ошибку, возникающую при доступе к изображению (правильно ли оно загружается, если вы не пытаетесь извлечь растровое изображение?). Код моего обновленного ответа действительно работает для меня. Я также заметил, как into(-1,-1) работает, чтобы получить полноразмерное изображение, я бы тоже попробовал. - person outlyer; 10.12.2014
comment
Моя проблема заключалась в том, что моим испытуемым была гифка. DOH. Это правильный ответ - спасибо! - person JohnnyLambada; 11.12.2014
comment
Для потомков вам не нужна асинхронная задача, просто используйте .override (int, int) и / или SimpleTarget - person Sam Judd; 13.12.2014
comment
@Monkeyless спасибо, я расширил свой ответ, включив ваше предложение. - person outlyer; 13.12.2014
comment
Если вы хотите получить растровое изображение в исходном размере, лучше передать Target.SIZE_ORIGINAL для ширины и высоты растрового изображения вместо -1. - person Alex Bonel; 26.06.2015
comment
Что делать, если требуется путь к изображению, поскольку мне нужно отправить изображение для копирования - person ingsaurabh; 17.11.2015
comment
Предложение @ AlexBonel правильное. -1 на меня разбился. Используйте TARGET_SIZE_ORIGINAL, чтобы получить исходный размер - person SIr Codealot; 26.01.2016
comment
Вы получите полноразмерное растровое изображение, если не предоставите какой-либо параметр для SimpleTarget, например: new SimpleTarget<Bitmap>(){....} - person Henry; 08.11.2016
comment
GlideAnimation не найдено. - person Nouman Ch; 05.04.2018
comment
В Glide 4.0.0+ используйте .asBitmap () before.load () и .submit (100, 100) вместо .into (100, 100) - person Yazon2006; 12.06.2018
comment
В android o Glide.with (context) .load (R.drawable.ic_default_danmu_head) .asBitmap (). CenterCrop (). Into (size, size) .get () возвращает значение null. - person Allen Vork; 21.06.2018
comment
FutureTarget устарел, как и SimpleTarget! - person Nux; 10.06.2019
comment
Bitmap bm = Glide.with (контекст) .asBitmap (). Load (путь) .submit (). Get (); - person Divyanshu Kumar; 26.02.2020

Похоже, что переопределение класса Target или одной из реализаций, таких как BitmapImageViewTarget, и переопределение метода setResource для захвата растрового изображения может быть выходом ...

Это не проверено. :-)

    Glide.with(context)
         .load("http://goo.gl/h8qOq7")
         .asBitmap()
         .into(new BitmapImageViewTarget(imageView) {
                     @Override
                     protected void setResource(Bitmap resource) {
                         // Do bitmap magic here
                         super.setResource(resource);
                     }
         });
person blad    schedule 10.12.2014
comment
Не примет ли Bitmap ширину / высоту imageView? Я надеюсь получить исходное неизмененное растровое изображение. - person JohnnyLambada; 10.12.2014
comment
Для Glide 4.0.0+ используйте .asBitmap () before.load () - person Saeed; 02.12.2019

ОБНОВЛЕНИЕ

Теперь нам нужно использовать Custom Targets.

КОД ОБРАЗЦА

    Glide.with(mContext)
            .asBitmap()
            .load("url")
            .into(new CustomTarget<Bitmap>() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {

                }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {
                }
            });

Как использовать скольжение для загрузки изображения в растровое изображение?

Все приведенные выше ответы верны, но устарели

потому что в новой версии Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

Вы найдете ниже ошибку в коде

  • .asBitmap() недоступен в glide:4.8.0

введите описание изображения здесь

  • SimpleTarget<Bitmap> устарел

введите описание изображения здесь

Вот решение

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;



public class MainActivity extends AppCompatActivity {

    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.imageView);

        Glide.with(this)
                .load("")
                .apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
                .into(new Target<Drawable>() {
                    @Override
                    public void onLoadStarted(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {

                    }

                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {

                        Bitmap bitmap = drawableToBitmap(resource);
                        imageView.setImageBitmap(bitmap);
                        // now you can use bitmap as per your requirement
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void getSize(@NonNull SizeReadyCallback cb) {

                    }

                    @Override
                    public void removeCallback(@NonNull SizeReadyCallback cb) {

                    }

                    @Override
                    public void setRequest(@Nullable Request request) {

                    }

                    @Nullable
                    @Override
                    public Request getRequest() {
                        return null;
                    }

                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onStop() {

                    }

                    @Override
                    public void onDestroy() {

                    }
                });

    }

    public static Bitmap drawableToBitmap(Drawable drawable) {

        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        int width = drawable.getIntrinsicWidth();
        width = width > 0 ? width : 1;
        int height = drawable.getIntrinsicHeight();
        height = height > 0 ? height : 1;

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }
}
person AskNilesh    schedule 09.01.2019
comment
Если вы попробуете asBItmap перед .load, это не даст вам никаких ошибок - person Vipul Chauhan; 26.01.2019
comment
@Spritzig, с какой проблемой вы столкнулись сейчас - person AskNilesh; 29.01.2019
comment
@NileshRathod Он не показывает мне значок, нет ошибки, ничего, а только не показывает значок. - person Abedin.Zhuniqi; 29.01.2019
comment
@NileshRathod Вы нашли в этом проблему? - person Abedin.Zhuniqi; 31.01.2019

Вот что сработало для меня: https://github.com/bumptech/glide/wiki/Custom-targets#overriding-default-behavior

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.transition.Transition;
import com.bumptech.glide.request.target.BitmapImageViewTarget;

...

Glide.with(yourFragment)
  .load("yourUrl")
  .asBitmap()
  .into(new BitmapImageViewTarget(yourImageView) {
    @Override
    public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> anim) {
        super.onResourceReady(bitmap, anim);
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {  
            @Override
            public void onGenerated(Palette palette) {
                // Here's your generated palette
                Palette.Swatch swatch = palette.getDarkVibrantSwatch();
                int color = palette.getDarkVibrantColor(swatch.getTitleTextColor());
            }
        });
    }
});
person Stephen Kaiser    schedule 24.06.2015

Если вы хотите присвоить динамическое растровое изображение переменным растрового изображения

Пример для kotlin

backgroundImage = Glide.with(applicationContext).asBitmap().load(PresignedUrl().getUrl(items!![position].img)).into(100, 100).get();

Приведенные выше ответы не помогли мне

.asBitmap должен быть перед .load("http://....")

person ramana vv    schedule 26.04.2018
comment
.into (100, 100) устарел, используйте .submit (100, 100) - person Yazon2006; 12.06.2018
comment
почему f делает glide осуждает такие вещи? это практически то же самое использование ... - person kkarakk; 30.03.2019

ОБНОВЛЕНИЕ НОВОЙ ВЕРСИИ

Glide.with(context.applicationContext)
    .load(url)
    .listener(object : RequestListener<Drawable> {
        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>?,
            isFirstResource: Boolean
        ): Boolean {
            listener?.onLoadFailed(e)
            return false
        }

        override fun onResourceReady(
            resource: Drawable?,
            model: Any?,
            target: com.bumptech.glide.request.target.Target<Drawable>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            listener?.onLoadSuccess(resource)
            return false
        }

    })
    .into(this)

СТАРЫЙ ОТВЕТ

Ответ @outlyer правильный, но в новой версии Glide есть некоторые изменения

Моя версия: 4.7.1

Код:

 Glide.with(context.applicationContext)
                .asBitmap()
                .load(iconUrl)
                .into(object : SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
                    override fun onResourceReady(resource: Bitmap, transition: com.bumptech.glide.request.transition.Transition<in Bitmap>?) {
                        callback.onReady(createMarkerIcon(resource, iconId))
                    }
                })

Примечание: этот код запускается в потоке пользовательского интерфейса, поэтому вы можете использовать AsyncTask, Executor или что-то еще для параллелизма (например, код @ outlyer). Если вы хотите получить исходный размер, укажите Target.SIZE_ORIGINA в качестве моего кода. Не используйте -1, -1

person Mạnh Hoàng Huynh    schedule 15.06.2018
comment
SimpleTarget ‹Bitmap› устарел в новой версии - person Nainal; 05.01.2019

Путь Котлина -

fun Context.bitMapFromImgUrl(imageUrl: String, callBack: (bitMap: Bitmap) -> Unit) {
    GlideApp.with(this)
        .asBitmap()
        .load(imageUrl)
        .into(object : CustomTarget<Bitmap>() {
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                callBack(resource)
            }

            override fun onLoadCleared(placeholder: Drawable?) {
                // this is called when imageView is cleared on lifecycle call or for
                // some other reason.
                // if you are referencing the bitmap somewhere else too other than this imageView
                // clear it here as you can no longer have the bitmap
            }
        })
}
person Anoop M Maddasseri    schedule 02.10.2020

для Glide версии 4.10.0: Glide.with (context) .download (mImageUrl) .submit (). get ()

person beokh    schedule 23.04.2021

в котлине вы можете использовать

CoroutineScope(Dispatchers.IO).launch {
      Glide.with(this@&YourActivity).asBitmap().load(imageUrl)                           
                        .listener(object : RequestListener<Bitmap> {
                            override fun onLoadFailed(
                                e: GlideException?,
                                model: Any?,
                                target: Target<Bitmap>?,
                                isFirstResource: Boolean
                            ): Boolean {
                                  Log.e("GlideException" ,"${e.message}")
                                return false
                            }

                            override fun onResourceReady(
                                resource: Bitmap?,
                                model: Any?,
                                target: Target<Bitmap>?,
                                dataSource: DataSource?,
                                isFirstResource: Boolean
                            ): Boolean {
                                resource?.let {bitmap->
                                    //here your bitmap is ready you can use it
                                }
                                return false
                            }

                        })
                        .submit().get()//by using this line glide lib behave as synchronously(block instructions until the task is completed) and by removing this line you can use it as a asynchronously(without blocking other operations)  
}

Я использую

api 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
person Abdur Rehman    schedule 18.06.2021

Более новая версия:

GlideApp.with(imageView)
    .asBitmap()
    .override(200, 200)
    .centerCrop()
    .load(mUrl)
    .error(R.drawable.defaultavatar)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .signature(ObjectKey(System.currentTimeMillis() / (1000*60*60*24))) //refresh avatar cache every day
    .into(object : CustomTarget<Bitmap>(){
        override fun onLoadCleared(placeholder: Drawable?) {}
        override fun onLoadFailed(errorDrawable: Drawable?) {
            //add context null check in case the user left the fragment when the callback returns
            context?.let { imageView.addImage(BitmapFactory.decodeResource(resources, R.drawable.defaultavatar)) }
        }
        override fun onResourceReady(
            resource: Bitmap,
            transition: Transition<in Bitmap>?) { context?.let { imageView.addImage(resource) } }
    })
person mrj    schedule 26.03.2020