java - 为什么图像质量下降?

标签 java android android-bitmap

我正在屏幕上显示图片:

 Bitmap bitmap = decodeSampledBitmapFromResource(data, 100, 100);

decodeSampledBitmapFromResource() 方法如下所示:

 public static Bitmap decodeSampledBitmapFromResource(String path,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }

使用Matrix将图片旋转90度后,图片质量下降:

Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap bitmap = decodeSampledBitmapFromResource(data, 100, 100);
bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

为什么显示的图片质量下降?以及如何使其达到正常质量?

旋转前的图片: enter image description here

旋转后的图片:

enter image description here

最佳答案

看起来您几乎直接从 documentation 提取代码,这很棒,但是您需要了解该代码在做什么。以这段代码为例:

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

我猜这与你的 calculateInSampleSize() 相同方法。此方法计算用于缩放图像以最佳匹配给定尺寸的除数。

就您而言,您提供 100px对于宽度和高度。这意味着如果起始图像是 680 x 600px,那么您的 inSampleSize将为 2,因此生成的图像将为 340 x 300px,这是质量损失。如果您不需要显示完整分辨率,这有助于减小图像大小,但在您的情况下,您似乎确实需要使用原始图像大小以所需的分辨率显示它。

并不意味着您应该放弃计算 inSampleSize ,这只是意味着您应该提供更适合您的 ImageView 的所需宽度和高度尺寸。

int requiredWidth = imageView.getMeasuredWidth();
int requiredHeight = imageView.getMeasureHeight();

Note: this will not work if the ImageView width and/or height is set to wrap_content, as the width and height will not be measured until a source image is provided.

就您而言,当您计算 inSampleSize 时,我还会交换所需的宽度和高度。因为您将图像旋转 90°:

options.inSampleSize = calculateInSampleSize(options, requiredHeight, requiredWidth);

最后,请确保您的 ImageView.ScaleType 设置为FIT_XY ,因为这会扭曲图像,导致感知到的质量损失。其他比例类型也可能增加图像的尺寸超出原始尺寸,这也可能导致明显的质量损失。

<小时/>

最后,如果您的应用程序显示大量图像,我建议您使用图像加载库来加载图像。这些库将处理缩放图像以适应 ImageView ,最支持wrap_content以及。 Glide , PicassoFresco这是一些很好的例子。

关于java - 为什么图像质量下降?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38526422/

相关文章:

java - 在源代码中包含 SVN 修订号

java - 如何在 JXTreeTable 中设置自定义 DefaultTreeCellRenderer

java - 从 rich :datatable binding table 获取行

Android Native Mobile First 依赖太多库?

java - 我的位图在缩放后在 Android 中旋转

java - JUnit 测试用例失败 : java. lang.AssertionError : expected null, 但为:<null>

android - 用 Dagger2 注入(inject) ViewModel

Android Fragment(与 2.3.3 上的兼容包)创建 "Specified child already has a parent error"

android - Android 4.1.2 上 ImageView 中的倾斜图像

Android - 在 BitmapFactory.decodeStream 返回之前调整图像大小