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

146

Загрузить URL-адрес в ImageViewGlide очень просто:

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

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

Джонни Ламбада
источник

Ответы:

189

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

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)

Ява:

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 очищается.

Максимум
источник
10
Я использую Glide 4.0 и не могу найти .asBitmap ()
Крис Невилл
9
Для синхронных вызовов используйте Glide.with (this) .asBitmap (). Load (pictureUrl) .submit (100, 100) .get (). Это может быть полезно, если вы хотите добавить значок в уведомление через .setLargeIcon (растровое изображение)
Yazon2006,
1
@Max эта работа для меня в реализации 'com.github.bumptech.glide: glide: 3.6.1'
Бипин Бхарти,
2
@Nux, убедитесь, что вы используете последнюю версию4.9.0
Макс,
1
.asBitmap()следует поставить после, with(this)если он не решен.
Alston
183

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

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

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

Примечание into(int,int)возвращает a 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 в комментарии ниже (и это, похоже, тоже официальный способ ), вы можете использовать a 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>()

Outlyer
источник
4
Для потомков вам не нужна асинхронная задача, просто используйте .override (int, int) и / или SimpleTarget
Сэм Джадд
2
@Monkeyless, спасибо, я расширил свой ответ, включив ваше предложение.
outlyer
33
Если вы хотите получить растровое изображение в исходном размере, лучше передать Target.SIZE_ORIGINALширину и высоту растрового изображения вместо -1
Алекс Бонель
5
Вы получите полноразмерное растровое изображение, если не предоставите какой-либо параметр, SimpleTargetподобный этому:new SimpleTarget<Bitmap>(){....}
Генри
3
В Glide 4.0.0+ используйте .asBitmap () before.load () и .submit (100, 100) вместо .into (100, 100)
Yazon2006,
16

Похоже, что переопределение 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);
                     }
         });
пузырек
источник
3
Не примет ли Bitmap ширину / высоту imageView? Я надеюсь получить исходное неизмененное растровое изображение.
JohnnyLambada
Для Glide 4.0.0+ используйте .asBitmap () before.load ()
Saeed
10

ОБНОВИТЬ

Теперь нам нужно использовать 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;
    }
}
Спросите
источник
Если вы попробуете asBItmap перед .load, то это не даст вам никаких ошибок
Випул Чаухан
@Spritzig, с какой проблемой вы столкнулись сейчас
AskNilesh
@NileshRathod Он не показывает мне значок без ошибок, ничего, а только не показывает значок.
Abedin.Zhuniqi
@NileshRathod Вы нашли в этом проблему?
Abedin.Zhuniqi
7

Это то, что сработало для меня: 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());
            }
        });
    }
});
Стивен Кайзер
источник
4

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

Пример для kotlin

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

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

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

Рамана В.В.
источник
4
.into (100, 100) устарел, используйте .submit (100, 100)
Yazon2006,
почему f не одобряет подобные вещи? это практически то же самое использование ...
kkarakk
2

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

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

Мун Хоанг Хюнь
источник
4
SimpleTarget <Bitmap> устарел в новой версии
Nainal
1

Котлинский путь -

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
            }
        })
}
Ануп М
источник
0

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

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) } }
    })
MRJ
источник