I'm seeing very ugly artifacting / jagged edges when I downsize an image on an Android device no matter what I try. I've gone through several potential solutions I found on StackOverflow and blogs, and everything seems to give me similar results.
Scaled Image (214 x 214) (notice the jagged edges):
What I have tried:
Canvas
using a Paint
with anti-aliasing, and filtering enabledBitmapFactory.decode
bitmap.scale()
All of the above trials have yielded almost the exact same result. This is such a common problem though, that surely I'm overlooking something, or not doing something properly.
If I use a web-based image-resizer, here is the result:
What it should look like:
What can I do to get the same results as the above image?
There is a tricky way to (manage to) achieve that only with standard APIs. Just avoid scaling down the bitmap at once.
Bitmap bitmap = BitmapFactory.decodeStream(stream);
:
Matrix m = new Matrix();
m.setScale(0.5F, 0.5F);
while (bitmap.getWidth() > 256)
{
Bitmap bitmap_half = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
bitmap.recycle();
bitmap = bitmap_half;
}
imageView.setImageBitmap(bitmap);
Result:
How this works:
Since the filter is short-ranged (primarily designed for scaling up e.g. bilinear or bicubic), it's useless for scaling down (=discrete resampling) in general cases. However it does refer neighboring pixels for calculating new pixel colors. So by avoiding too sparse resampling, it's possible to make it work as a smoothing filter for scaling down. maybe.