Skewed images in ImageView on Android 4.1.2

2019-05-07 12:05发布

问题:

I have an app that displays an image in an ImageView, and am experiencing problem specifically for Android 4.1.2. It is confirmed to not work on three separate 4.1.2 devices, while working on 2.3.7, 4.2.1, 4.3 and 4.4.2. The error occurs for several different images, but not all. There seems to be something about some specific JPEG-files that doesn't work as intended.

How it actually looks, and how it shows on Android 4.1.2:

The above image (left) is one such problematic image file.

A summary of the code behind setting the displayed image is:

Bitmap bitmap, background;
ImageView imageView = (ImageView)findViewById(R.id.imageView);

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPurgeable = true;
options.inInputShareable = true;
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog, options);

background = bitmap.copy(Bitmap.Config.RGB_565, true);

Canvas canvas = new Canvas(background);
canvas.drawBitmap(bitmap, 0, 0, null);
// Some calls to canvas.drawText(....) here, but doesn't have to happen for the error to occur

imageView.setImageBitmap(background);

I've figured that I am able to resize and re-save the above photo in Photoshop to make it work, without knowing why. Since I have several I'd prefer not having to do so.

I am wondering what is the source of this error on Android 4.1.2, and if there might be some programmatic way of fixing it?

I've tried my luck on Google view "skewed", "tilted", "distorted" and similar, but there are very few mentions of it and no fixes. This is the mention with screenshot I've found:

  • Anyone else getting distorted album art in Play Music? (Screenshot)

回答1:

Based on the comment of rupps I changed from:

bitmap.copy(Bitmap.Config.RGB_565, true)

To:

bitmap.copy(Bitmap.Config.ARGB_8888, true)

This did in fact solve the problem for 4.1.2 devices, while remaining similar in functionality for all other tested devices. This does programatically solve my issue. Note however that it does require double the memory, as each pixel is stored on 4 bytes instead of 2 bytes.

As for the source of the problem, I read from the documentation of RGB_565 that:

This configuration can produce slight visual artifacts depending on the configuration of the source.

I think this mostly relates to banding/color/dithering issues and this does not explain the version specific problem, but perhaps why this setting is troublesome.