Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JPEG images loaded from disk cache look weird #63

Closed
nemphys opened this issue Feb 24, 2014 · 16 comments
Closed

JPEG images loaded from disk cache look weird #63

nemphys opened this issue Feb 24, 2014 · 16 comments

Comments

@nemphys
Copy link
Contributor

nemphys commented Feb 24, 2014

Hi, I have been using this library in my new project and I must say it is amazing!
The only issue I have is that when jpeg (not png, those are absolutely fine) images are loaded from disk cache, they look like their color palette has been reduced; white gradients take a greenish hue, etc.
This only happens when using disk cache, since when the images are first downloaded (or loaded from memory cache), they look fine.
I tried setting the image compression quality of the ImageManager to 100 with no apparent effect.
Any help would be appreciated...

@sjudd
Copy link
Collaborator

sjudd commented Feb 24, 2014

Thanks, hope you find it useful!

I think I've seen a similar quality issues on certain devices. Are you seeing this on a particular device and/or version of Android? If you try simply writing the decoded jpeg to a temporary file and then decoding it, does the newly decoded bitmap have the same quality issues? The image is written to disk using the framework Bitmap#compress method and the code is pretty straightforward here:

https://github.com/bumptech/glide/blob/master/library/src/com/bumptech/glide/resize/ImageManager.java#L535

As far as I can tell we do use the quality you set, though the default is definitely < 100.

@nemphys
Copy link
Contributor Author

nemphys commented Feb 25, 2014

It is not on some specific device, since I have tested it both on my Galaxy S4 and 2 emulators.
As I told you, quality setting made no difference (default is 90 I think), so it should have nothing to do with that.
Can you please be more specific on what I am supposed to do as a test?
Thanx.

@sjudd
Copy link
Collaborator

sjudd commented Feb 27, 2014

I'm looking in to this. Can you paste the Glide.load... line you're using? I'm guessing one of the transformations or the downsampling may reduce the quality, but I haven't been able to replicate this yet.

@nemphys
Copy link
Contributor Author

nemphys commented Feb 27, 2014

I'm not using anything fancy, just a Glide.load(url).listener(x).into(imageView) (the listener is just for a fadein animation, since I want it to happen even when the item comes from cache; there should be a setting for that btw).
I also tried adding a .asIs() in there, since it's supposed to disable the downsampler altogether, but it did not work.
If you can point me to the right place, I can try switching things on/off (I have the source of Glide in my project, so it should be very easy) in order to spot the issue.

@sjudd
Copy link
Collaborator

sjudd commented Feb 27, 2014

Thanks for being willing to look in to this. Saving to the cache happens in my earlier link (which we seem to have established is not the issue), loading the image into memory happens in the downsampler (https://github.com/bumptech/glide/blob/master/library/src/com/bumptech/glide/resize/load/Downsampler.java). When you just use load().into(), there is a transformation also (https://github.com/bumptech/glide/blob/master/library/src/com/bumptech/glide/resize/load/Transformation.java#L33). Using load().asIs() should disable the transformation, but it's always possible there's a bug.

@nemphys
Copy link
Contributor Author

nemphys commented Feb 28, 2014

Hmm... After looking a little into it, it seems that the framework Bitmap#compress is the culprit: it seems that whatever quality setting one sets, there is always a quality degradation. Other peopler seem to have the same problem (see https://groups.google.com/forum/#!topic/android-developers/q7oysr45kSI and https://groups.google.com/forum/#!topic/android-developers/C3savvS2pqs) and the only real solution I saw was "save it using a lossless format -> PNG".
When I changed the ImageManager#putInDiskCache code to always use PNG as the format, all is well.
I am wondering how come no other user of this library has ever mentioned this (is everybody using pngs?)...
Since forking for such a minor change is not worth it, I am wondering if we could just add some option eg. to always use png (or to set what format to use) when saving to disk cache somewhere.
Do you think this is possible?

@sjudd
Copy link
Collaborator

sjudd commented Mar 2, 2014

We can absolutely add an option to make this possible, though it will require changing the code. I'm not sure why no one else has brought it up, I can definitely see it being a framework issue.

If you want to put up a pull request to add this yourself, please feel free! Your best bet is to revive setBitmapCompressFormat: https://github.com/bumptech/glide/blob/master/library/src/com/bumptech/glide/resize/ImageManager.java#L231. You can just set a bitmap compress format as an instance variable in ImageManager (default to null if none is set rather than the current JPEG), and then change the compress code (https://github.com/bumptech/glide/blob/master/library/src/com/bumptech/glide/resize/ImageManager.java#L527) to use the given compress format if it's not null, or continue to do what it's doing now if the compress format is null.

@sjudd
Copy link
Collaborator

sjudd commented Mar 5, 2014

Going to call this closed, feel free to reopen if you still see issues. Thanks for reporting and looking in to this!

@sjudd sjudd closed this as completed Mar 5, 2014
@abuddy
Copy link

abuddy commented Oct 6, 2014

I have a problem on my Moto X. I think it might be related. I use Glide to load the images in a ListView (lazy) in the getView method of my list adapter. I notice the banding, especially on the images that have smooth gradients. The images look fine in Chrome browser though. And it's not only the disk cache, unless Glide first writes the files after downloading, then reads from disk and then loads them into the ImageView.

The code that I use:

    Glide.with(this.context)
            .load(targetUrl)
            .override(500, 500)
            .placeholder(R.drawable.artwork_placeholder)
            .thumbnail(0.1f)
            .into(target);

I use Glide 3.3.1

@sjudd sjudd reopened this Oct 7, 2014
@sjudd
Copy link
Collaborator

sjudd commented Oct 7, 2014

You're probably seeing the same issue as described here, but the API to change the format has changed:

BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
StreamBitmapDecoder decoder = new StreamBitmapDecoder(Downsampler.AT_LEAST, bitmapPool,
        DecodeFormat.ALWAYS_ARGB_8888);
Glide.with(yourFrament)
    .load(url)
    .asBitmap()
    .imageDecoder(decoder);

I know this is rather clunky, so I opened #177 to track making this easier.

@abuddy
Copy link

abuddy commented Oct 7, 2014

Thanks, that works, but I still have the problem when writing to disk. Sorry, I'm not that familiar with Glide, could you post the code to always write as PNG? And it's not that it's clunky, I think you just should add the above code to the wiki.

It also seems that when using .asBitmap(), there is no fade-in animation when the images are loaded, how could one fix that?

@sjudd
Copy link
Collaborator

sjudd commented Oct 10, 2014

Sorry for the slow response.

The cross fade animation is done using a TransitionDrawable. Since asBitmap() means you load a bitmap, we can't automatically do the crossfade for you. That said, you can use a normal view animation using on one of the animate() methods.

You can use .encode() to set a [BitmapEncoder](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/resource/bitmap/BitmapEncoder.html#BitmapEncoder%28android.graphics.Bitmap.CompressFormat, int%29) with whatever compression format and quality you want.

Just FYI, compressing a given Bitmap to a PNG often takes around 10x longer than compressing the same Bitmap to a JPEG. The biggest difference in quality should be using ARGB_8888, so it might be worth just playing the the jpeg compression level and seeing if you can get acceptable quality without always using PNGs (assuming you don't have all transparent images).

@abuddy
Copy link

abuddy commented Oct 11, 2014

The problem is, when you compress a JPEG image that was already compressed, the artifacts from the previous compression get worse and become very apparent. The way around this would be downloading the JPEG file and saving it directly to disk, without tinkering with it.

@sjudd
Copy link
Collaborator

sjudd commented Oct 11, 2014

Interesting, makes sense. In that case you you should take a look at the DiskCacheStrategy enum and corresponding builder method diskCacheStrategy().

Using SOURCE or ALL will make Glide download the bytes of whatever image you request directly into the cache and then decode the original untouched image. ALL will also cause any thumbnail you create (using a transformation or by downsampling) to be cached as well so if you want the highest quality possible SOURCE is probably your best bet. ALL might make sense if you also want to show small thumbnails where quality matters less.

@sjudd
Copy link
Collaborator

sjudd commented Oct 11, 2014

Also I did some digging today and there is an issue here. Using either BitmapRequestBuilder#format() or the method I described above only sets the format for decoding images from source, cached images are still decoded using the default (RGB_565 for non-transparent images). I'll put in a fix for at least the call to format()

@sjudd
Copy link
Collaborator

sjudd commented Oct 12, 2014

I opened a separate bug for tracking the format() issue I mentioned above: #187. Since this bug refers to an issue in Glide 2.x, I'm going to re-close this, but feel free to keep commenting on #187 or on our discussion list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants