¿Cómo se usa glide para descargar una imagen en un mapa de bits?

141

Descargar una URL en un ImageViewes muy fácil usando Glide:

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

Me pregunto si puedo descargar en un Bitmaptambién? Me gustaría descargar en un mapa de bits sin procesar que luego puedo manipular con otras herramientas. He leído el código y no veo cómo hacerlo.

JohnnyLambada
fuente

Respuestas:

176

Asegúrate de estar en la última versión

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

Kotlin:

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
            }
        })

Tamaño de mapa de bits:

si desea usar el tamaño original de la imagen, use el constructor predeterminado como se indicó anteriormente, de lo contrario, puede pasar el tamaño deseado para el mapa de bits

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) {
            }
        });

Vieja respuesta:

Con compile 'com.github.bumptech.glide:glide:4.8.0'y debajo

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

Para compile 'com.github.bumptech.glide:glide:3.7.0'y debajo

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

Ahora puedes ver una advertencia SimpleTarget is deprecated

Razón:

El punto principal de desaprobar SimpleTarget es advertirle sobre las formas en que lo tienta a romper el contrato de API de Glide. Específicamente, no hace nada para obligarlo a dejar de usar cualquier recurso que haya cargado una vez que se borre SimpleTarget, lo que puede provocar bloqueos y corrupción gráfica.

La imagen SimpleTargetfija se puede usar siempre y cuando se asegure de que no está usando el mapa de bits una vez que se borre el imageView.

Max
fuente
10
Estoy en Glide 4.0 y parece que no puedo encontrar .asBitmap ()
Chris Nevill
8
Para llamadas sincrónicas, use Glide.with (this) .asBitmap (). Load (pictureUrl) .submit (100, 100) .get (). Puede ser útil cuando desea agregar un icono en la notificación a través de .setLargeIcon (mapa de bits)
Yazon2006
1
@Max este trabajo es para mí en la implementación 'com.github.bumptech.glide: glide: 3.6.1'
Bipin Bharti
2
@Nux asegúrate de tener la última versión4.9.0
máximo
1
.asBitmap()debe colocarse después with(this)si no está resuelto.
Alston
177

No estoy lo suficientemente familiarizado con Glide, pero parece que si conoce el tamaño objetivo, puede usar algo como esto:

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

Parece que puede pasar -1,-1y obtener una imagen a tamaño completo (puramente basada en pruebas, no puedo verla documentada).

Note into(int,int)devuelve a FutureTarget<Bitmap>, por lo que debe envolver esto en una cubierta de bloque try-catch ExecutionExceptiony InterruptedException. Aquí hay un ejemplo de implementación más completo, probado y funcionando:

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

Siguiendo la sugerencia de Monkeyless en el comentario a continuación (y esta parece ser también la forma oficial ), puede usar un SimpleTarget, opcionalmente, override(int,int)para simplificar el código considerablemente. Sin embargo, en este caso se debe proporcionar el tamaño exacto (no se acepta nada por debajo de 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()
        }
    });

como sugirió @hennry si necesitabas la misma imagen, usanew SimpleTarget<Bitmap>()

outlyer
fuente
44
Para la posteridad, no necesita la tarea asíncrona, solo use .override (int, int) y / o un SimpleTarget
Sam Judd
2
@Monkeyless gracias, he ampliado mi respuesta para incluir su sugerencia.
Outlyer
33
Si desea lograr un mapa de bits en tamaño original, es mejor pasar Target.SIZE_ORIGINALpor el ancho y la altura del mapa de bits en lugar de -1
Alex Bonel
55
Obtendrá el mapa de bits de tamaño completo si no proporciona ningún parámetro para SimpleTargetesto:new SimpleTarget<Bitmap>(){....}
Henry
3
En Glide 4.0.0+ use .asBitmap () before.load () y .submit (100, 100) en lugar de .into (100, 100)
Yazon2006
16

Parece que anular la Targetclase o una de las implementaciones BitmapImageViewTargety anular el setResourcemétodo para capturar el mapa de bits podría ser el camino a seguir ...

Esto no ha sido probado. :-)

    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);
                     }
         });
vejiga
fuente
3
¿El mapa de bits no tomará el ancho / alto de la imageView? Espero obtener el mapa de bits original inalterado.
JohnnyLambada
Para Glide 4.0.0+ use .asBitmap () before.load ()
Saeed
10

ACTUALIZAR

Ahora necesitamos usar Custom Targets

CÓDIGO DE MUESTRA

    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) {
                }
            });

¿Cómo se usa glide para descargar una imagen en un mapa de bits?

Las respuestas anteriores son correctas pero desactualizadas

porque en la nueva versión de Glide implementation 'com.github.bumptech.glide:glide:4.8.0'

Encontrará el siguiente error en el código

  • El .asBitmap()no está disponible englide:4.8.0

ingrese la descripción de la imagen aquí

  • SimpleTarget<Bitmap> es obsoleto

ingrese la descripción de la imagen aquí

Aquí hay solución

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;
    }
}
Nilesh Rathod
fuente
Si prueba asBItmap antes de .load para que no le dé ningún error
Vipul Chauhan
@Spritzig, ¿qué problema estás enfrentando ahora?
Nilesh Rathod
@NileshRathod No me muestra el icono sin error, pero solo no muestra el icono.
nideba
@NileshRathod ¿Has encontrado el problema para esto?
nideba
7

Esto es lo que funcionó para mí: 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());
            }
        });
    }
});
Stephen Kaiser
fuente
4

Si desea asignar una imagen de mapa de bits dinámica a variables de mapa de bits

Ejemplo para kotlin

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

Las respuestas anteriores no me funcionaron

.asBitmap debe ser antes de la .load("http://....")

ramana vv
fuente
44
.into (100, 100) está en desuso uso .submit (100, 100)
Yazon2006
¿Por qué la plaga se desliza en desuso cosas como esta? es prácticamente el mismo uso ...
kkarakk
2

ACTUALIZACIÓN PARA NUEVA VERSIÓN

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)

ANTIGUA RESPUESTA

La respuesta de @ outlyer es correcta, pero hay algunos cambios en la nueva versión de Glide

Mi versión: 4.7.1

Código:

 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))
                    }
                })

Nota: este código se ejecuta en UI Thread, por lo tanto, puede usar AsyncTask, Executor o algo más para la concurrencia (como el código de @ outlyer) Si desea obtener el tamaño original, coloque Target.SIZE_ORIGINA como mi código. No uses -1, -1

Mạnh Hoàng Huynh
fuente
44
SimpleTarget <Bitmap> está en desuso en una nueva versión
Nainal el
-1

Versión más nueva:

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
fuente