Glide: Can't load HQ image on Android 4.4.4

Created on 10 Oct 2016  路  10Comments  路  Source: bumptech/glide

Image size is 4200x1960, does not show it on Android 4.4 but shows it on Android 5, 6. Image size is 2.5MB, image url is http://cdn.skylife.com/minw_1920/upload/image/destinasyonlar/istanbul/galeri/adim_adim/Suleymaniyecamii_jpg.jpg (if still alive)

Glide version 3.7.0, okhttp3-integration version 1.5.0-SNAPSHOT

question

All 10 comments

Please fill in the issue template, there's no point me asking those questions one by one.

My blind suspicion is that you're load a SIZE_ORIGINAL image and the texture size is too small. See https://github.com/bumptech/glide/wiki/Debugging-and-Error-Handling how to show the exception if any.

Glide Version: 3.7.0

Integration libraries: okhttp3-integration version 1.5.0-SNAPSHOT

Device/Android Version: 4.4.4

Issue details / Repro steps / Use case background:
Image size is 4200x1960, does not show it on Android 4.4 but shows it on Android 5, 6. Image size is 2.5MB, image url is http://cdn.skylife.com/minw_1920/upload/image/destinasyonlar/istanbul/galeri/adim_adim/Suleymaniyecamii_jpg.jpg (if still alive)

Glide load line / GlideModule (if any) / list Adapter code (if any):

Glide.with(image.getContext())
                .load(photo.getPhotoUrl())
                .asBitmap()
                .dontAnimate()
                .placeholder(image.getDrawable())
                .thumbnail(Glide.with(image.getContext())
                        .load(photo.getThumbnailUrl())
                        .asBitmap()
                        .diskCacheStrategy(DiskCacheStrategy.SOURCE))
                .listener(new GlideDrawableLoadListener() {
                    @Override
                    public void onSuccess(String url) {
                        if (url.equals(photoUrl)) {
                            if (loadListener != null) {
                                loadListener.onLoaded();
                            }
                        }
                    }

                    @Override
                    public void onFail(String url) {
                        if (loadListener != null) {
                            loadListener.onFailed();
                        }
                    }
                })
                .into(new GlideImageTarget(image));

Layout XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:wheel="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_itemPhotoGallery_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<ImageVIew
        android:id="@+id/imageView_itemPhotoGallery"
        android:layout_width="match_parent"
        android:layout_gravity="center"
        android:layout_height="match_parent" />
</FrameLayout>

Stack trace / LogCat:
I dont see any log with Glide tag but i see this when i load image every time

W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (4200x1960, max=4096x4096)

You are right i guess about texture size, any suggestion, should i request smaller image, is there any callback to detect this?

No, because the Bitmap can be created, but not drawn. So it's a regular Android issue.

However, the reason why you're getting this lies within GlideImageTarget. What's wrong with the built-in targets? You're probably extending SimpleTarget or doing something clever that disables Glide's ability to load an image that is renderable. Please explain why you need that custom target and share its code. Hopefully I can suggest an alternative that works in every case.

Huh, that target looks safe. I think the problem may be then with sizing. Since it's an ImageViewTarget it actually reads the correct size from the view. Which, from the XML, looks like it's full screen. Older devices that are running Android 4 are potentially HD, or FullHD which means the resolution is, say, 1920x1080. Your source is 4200x1960. Since you're not using transformations (custom target disables the magic of GenericRequestBuilder.into(ImageView)), your only resizing happens when the downsampler actually decodes the image. Assuming your screen has the same orientation as the image, this means that the image will be decoded full size. This is because inSampleSize can only be power of two, but if you half the image size to 2100x980 that's under 1080 which is not allowed with the default downsample strategy (see Downsampler.AT_LEAST). To fix this you either need to use AT_MOST which is tricky, or just put a .fitCenter() on your load. _Note: if your input image was 4200x2160 or more than 2160, everything would appear to work until you get an image whose size downsamples differently._

.fitCenter() fixes problem but it does not show image in downloaded size this time, it shows too small image resolution. Any Downsampler.AT_LEAST sample?

Yes, Glide loads a perfectly sized image for the view: consumes the least possible memory, with the highest necessary quality. Can you please expand on "too small"? Is it possible you're seeing 565 format artifacts?
Here's a downsample example: https://github.com/bumptech/glide/issues/63#issuecomment-58124510

When i zoom the HQ picture with .fitCenter(), it does not show detail good. Without .fitCenter() zooming the picture gives perfect detail

Ah, I see. I didn't fully realise you were zooming, though I should have from the target from the gestureviews repo. With AT_MOST you may get a potentially smaller image than with fitCenter. I suggest you take another course of action. I see two options:

  • get the openGL texture size and use .override(txSize, txSize) to load the highest possible resolution Android can handle
  • change to another library that can handle tiled loading and zooming instead of requiring a single huge Bitmap to zoom.

thanks @TWiStErRob

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sant527 picture sant527  路  3Comments

billy2271 picture billy2271  路  3Comments

Tryking picture Tryking  路  3Comments

Ncit picture Ncit  路  3Comments

ghost picture ghost  路  3Comments