我正在屏幕上显示图片:
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);
为什么显示的图片质量下降?以及如何使其达到正常质量?
旋转后的图片:
最佳答案
看起来您几乎直接从 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 towrap_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 , Picasso和 Fresco这是一些很好的例子。
关于java - 为什么图像质量下降?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38526422/