krop
krop copied to clipboard
Bug: Cropping doesn't work well on high-resolution images
When I choose a high resolution image, and zoom in, it shows it very blurry, even though in reality when I zoom in on it inside a photo app, it shows fine, and then when I choose to crop, it will stay blurry.
Here's an example image to test: http://img.gawkerassets.com/img/18tbvl3htulmyjpg/original.jpg
Try to zoom in and crop the most left car. Using a photo app, I get this:
Using this library, I get this:
Current implementation does not support tiling, so it downscales large images. Currently, it works as intended.
@solkin are there plans to support large images?
Why downscale it to an image that has low quality though? And why not use partial decoding instead? This way you don't have to load the entire photo. Here: https://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html
Available from Android API 10...
I was talking about the way the image is displayed: we load subsampled image. That is why you see it with such a low quality. Then current implementation simply crops loaded bitmap. This is the way it is right now.
Using BitmapRegionDecoder is one solution. It will work if the crop region is small. However, when performing crop, we will need to load it into memory and save into new file. So even with BitmapRegionDecoder, provided that you want to keep original quality, we still can get OutOfMemoryError on large image if our cropping region is too large. :(
https://stackoverflow.com/questions/12032847/crop-a-portion-of-a-large-bitmap-without-outofmemory-android
If we want to avoid losing image quality, we should probably look into some native libs.
I see. I still have a few questions:
-
Can you at least consider avoid downsampling on Android 8.0+ when possible? On these versions, the Bitmap is stored on the native memory, so OOM is possible only when you really handle an impossibly large image.
-
How does the gallery app do it? Is it open sourced? Maybe you can grab the code from it? How can one obtain the code of i?
-
How does this library do it: https://github.com/ArthurHub/Android-Image-Cropper ?
-
I think it could also work this way: You've explained about the potential of OOM, but what I did here is to crop a very small rectangle of the image. As long as it's possible to do it, it should try to decode the partial area. Only if there are detected issues while doing so, it should downsample, and tell us it's downsampled.
-
I've heard bitmaps were in native memory on Android 2.x and earlier, then later they changed it. Didn't know they moved back to native on 8.0+. We will look into it!
-
There are libraries, that can show large images, for example https://github.com/davemorrissey/subsampling-scale-image-view I believe standard gallery app does the same.
-
He is catching OutOfMemoryError, interesting hack :) https://github.com/ArthurHub/Android-Image-Cropper/blob/1bf68d4b7992655a9c755e7afb824f8847df1672/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapUtils.java#L166 He tries to load image with original scale, then downscales it until it is loaded without OOM. Looks like he will still loose quality when both image and crop region are large.
-
I agree, when you crop small area in a large image, you can keep the original quality (or at least won't make it that blurry). Perhaps, if we use BitmapRegionDecoder together with the hack from the library you mentioned, we can improve our image cropper for your use-case. Anyway, I think in order to load and display the image, we should use SubsamplingScaleImageView or similar, otherwise it will be blurry.
-
On 2.x and earlier, this is true, but it worked in a weird way: if you reached the heap max size, you'd still get OOM, even though the Bitmap is in the "normal" RAM. So, it was as if it's in the heap memory, and you had to call 'recycle' on it too, because it wasn't really on the heap. In short, a nightmare of memory management.
-
I meant the cropping part, and not just displaying images...
-
Well it's better than crashing though. I don't think it will tell you that it got the low quality crop though.
-
You think it's possible to just use what they have on SubsamplingScaleImageView , and make it crop-able ?