Glide: Scale images according to display density

Created on 8 Oct 2015  路  3Comments  路  Source: bumptech/glide

Hi.
I need to display images of varying sizes in a full-screen ImageView with scaleType="centerInside". Size of the images is unknown at the moment of loading but they are all in mdpi density and server cannot resize them on-the-fly. During the loading I have to upscale them so each image has the same size on different screen densities, e.g. 32x32 images should be scaled to 64x64 on xhdpi, 96x96 on xxhdpi.
What is the right way to perform such resizing using Glide?

I can illustrate the desired behavior using the following code:

// R.drawable.test is located in drawable-nodpi
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
bitmap.setDensity(160);
imageView.setImageBitmap(bitmap);

The bitmap will be scaled 2x on xhpi, 3x on xxhdpi, etc.

question

All 3 comments

Glide doesn't know about dp sizes. If your target in XML has a fixed dp size it'll appear "the same size" on all devices as per Android's specs. Glide only reads the size of these view which are in pixels. Do you really need a full screen ImageView, why can't the Android layouts do the work of figuring out the size for you (wrap_content)?

I would try the following:

Glide
        .with(getActivity())
        .load(url)
        .dontTransform()
        .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) // worth a try without this line too
        .sizeMultiplier(getResources().getDisplayMetrics().density)
        .into(imageView)
;

however, sadly, you will bump into #508, but still worth a try, maybe without .override() it works.
So while that's not fixed, I recommend writing a a BitmapTransformation yourself, which essentially ignores outWidth/outHeight and scales the Bitmap by the same .density as the above code.

Another hackier alternative may be:

Glide
        .with(getActivity())
        .load(url)
        .asBitmap()
        .dontTransform()
        .listener(new RequestListener<String, Bitmap>() {
            @Override public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
                return false;
            }
            @Override public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target,
                    boolean isFromMemoryCache, boolean isFirstResource) {
                resource.setDensity(getResources().getDisplayMetrics().densityDpi);
                return false;
            }
        })
        .into(imageView)
;

In all cases be careful with Bitmap pooling. I'm not sure how that will react to setting the density on the Bitmaps.

@TWiStErRob thanks for your response. Unfortunately sizeMultiplier only accepts values from 0 to 1 but listener did the trick. Thanks!

The listener approach did not work for me. I have one device with a max width of 320dp and another at 411dp. This solution does not make the image smaller for the 320dp device.

Also, how can I use .bitmapTransform() with the listener?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mttmllns picture mttmllns  路  3Comments

r4m1n picture r4m1n  路  3Comments

Tryking picture Tryking  路  3Comments

billy2271 picture billy2271  路  3Comments

colinrtwhite picture colinrtwhite  路  3Comments