Background
Creating an app that has a lot of high quality images, I've decided to downscale the images to the needed size (meaning that if the image is larger than the screen , I downscale it ) .
The problem
I've noticed that on some devices, if the images are downscaled, they become blurry/pixelated, yet on the same devices, for the same target imageView size, if the images aren't downscaled, they look just fine.
What I've tried
I've decided to check this issue further, and created a small POC app that shows the issue.
Before showing you code, here's a demo of what I'm talking about :
it's a bit hard to see the difference, but you can see that the second is a bit pixelated . this can be shown on any image.
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>
The question
Why does it occur?
Both methods should have the same result, as both sample from the same source and using the same factor.
I've tried to play with the downsampling method, but nothing has helped.
Using the inDensity (instead of inSampleSize) seems to fix it, but I'm not sure what to set for it . i think that for outside images (from the internet for example), i can set it to the screen density multiplied by the sample size i wish to use.
But is it even a good solution? what should i do in the case the images are inside the resources folder (i don't think there is a function to get which density folder a bitmap is located at) ? why does it work while using the recommended way (talked about here) doesn't work well ?
EDIT: I've found out a trick to get which density is used for a drawable you get from the resources (link here) . however, it isn't future proof, as you need to be specific to the density to detect.