我在屏幕上显示图片:
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);
}
使用矩阵将图片旋转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);
为什么显示图片的质量下降?以及如何使其达到正常质量?
轮换后的图片:
答案 0 :(得分:2)
看起来您几乎是直接从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();
注意:如果
ImageView
宽度和/或高度为{<1}},则将不会工作 设置为wrap_content
,因为直到a才会测量宽度和高度 提供源图像。
在您的情况下,我还会在您计算inSampleSize
时交换所需的宽度和高度,因为您将图像旋转90°:
options.inSampleSize = calculateInSampleSize(options, requiredHeight, requiredWidth);
最后,请确保您的ImageView.ScaleType
不设置为FIT_XY
,因为这会使图像失真,从而导致质量下降。其他比例类型也可以增加图像的大小超出原始尺寸,这也可能导致感知质量下降。
最后,如果您的应用程序显示了大量图像,我建议使用图像加载库为您加载图像。这些库将处理缩放图像以适合ImageView
,并且大多数支持wrap_content
。 Glide,Picasso和Fresco是一些很好的例子。