背景
我正在创建一个包含大量高质量图片的应用程序,因此我决定将图片缩小到所需的大小(也就是说,如果图像比屏幕大,我会将其缩小)。
问题
我注意到在某些设备上,如果图片被缩小,它们会变得模糊/有锯齿,然而在同一设备上,对于相同的目标imageView大小,如果图片没有被缩小,它们看起来就很好。
尝试过的方法
我决定进一步检查这个问题,并创建了一个小型POC应用程序来展示这个问题。
在展示代码之前,这里有一个演示你所讲的:
虽然很难看出差异,但你可以看到第二张图片有点失真。这种情况可以在任何图像上显示。
public class MainActivity extends Activity
{
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView originalImageView=(ImageView)findViewById(R.id.originalImageView);
final ImageView halvedImageView=(ImageView)findViewById(R.id.halvedImageView);
final ImageView halvedBitmapImageView=(ImageView)findViewById(R.id.halvedBitmapImageView);
//
final Bitmap originalBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.test);
originalImageView.setImageBitmap(originalBitmap);
halvedImageView.setImageBitmap(originalBitmap);
//
final LayoutParams layoutParams=halvedImageView.getLayoutParams();
layoutParams.width=originalBitmap.getWidth()/2;
layoutParams.height=originalBitmap.getHeight()/2;
halvedImageView.setLayoutParams(layoutParams);
//
final Options options=new Options();
options.inSampleSize=2;
// options.inDither=true; //didn't help
// options.inPreferQualityOverSpeed=true; //didn't help
final Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.test,options);
halvedBitmapImageView.setImageBitmap(bitmap);
}
}
XML:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity"
android:fillViewport="true">
<HorizontalScrollView android:layout_width="match_parent"
android:fillViewport="true" android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="original" />
<ImageView android:layout_width="wrap_content"
android:id="@+id/originalImageView" android:layout_height="wrap_content" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="original , imageView size is halved" />
<ImageView android:layout_width="wrap_content"
android:id="@+id/halvedImageView" android:layout_height="wrap_content" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="bitmap size is halved" />
<ImageView android:layout_width="wrap_content"
android:id="@+id/halvedBitmapImageView" android:layout_height="wrap_content" />
</LinearLayout>
</HorizontalScrollView>
</ScrollView>
问题
为什么会出现这种情况?
两种方法应该有相同的结果,因为它们都从同一来源采样,使用相同的因素。
我已经尝试过调整降采样方法,但没有任何帮助。
使用inDensity(而不是inSampleSize)似乎可以解决这个问题,但我不确定应该设置什么。我认为对于外部图像(例如来自互联网的图像),我可以将其设置为屏幕密度乘以所需使用的采样大小。
但这真的是一个好的解决方案吗?如果图像在资源文件夹中怎么办(我不认为有一个函数可以获取位图位于哪个密度文件夹中)?为什么使用推荐的方式(在这里讨论)效果不好?
编辑:我发现了一个技巧,可以获取从资源中获取的可绘制对象使用的密度(链接在此处)。然而,它并不具备未来的可扩展性,因为您需要特定的密度才能检测。