0

I am running into a strange issue. I have multiple images in my Android project which I stored as .png files under res\drawable. I was able to easily extract the images at runtime and convert them to a bitmap like this:

Drawable d = getResources().getDrawable(R.drawable.imageId);
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();

This works great and the image gets scaled correctly no matter what screen density the device has. All my images are 200 pixels by 200 pixels and my image layout is configured as 200 dip x 200 dip.

Now, I have stored all images as blobs in an SQlite database due to scalability issues and I am extracting them at runtime and converting to a bitmap like this:

byte[] bb = cursor.getBlob(columnIndex);
Bitmap bitmap = BitmapFactory.decodeByteArray(bb, 0, bb.length);

The image displays fine if the screen density is standard 160 dip. But if the density is any less or more, the image doesn't scale and remains 200 pixels x 200 pixels for 160 dip. So basically, on a smaller screen (120 dip), the image takes more space than it should and on a larger screen (240 dip), it takes less space than it should.

Has anyone else run into this bizarre issue? Any explanation, workaround, solution will be really appreciated.

Thanks much in advance!

Ritesh
  • 11
  • 2

3 Answers3

1

Okay, I finally got it to work by using createScaledBitmap().

After creating a bitmap from the blob, I calculate the scaling factor and then calculate the new width and height. I then use those in the createScaledBitmap() function. Here's the code that works:

public static Bitmap getImageFromBlob(byte[] mBlob) 
{
    byte[] bb = mBlob;
    Bitmap b = BitmapFactory.decodeByteArray(bb, 0, bb.length); 
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int newWidth = b.getWidth()*metrics.densityDpi)/DisplayMetrics.DENSITY_DEFAULT;
    int newHeight = b.getHeight()*metrics.densityDpi)/DisplayMetrics.DENSITY_DEFAULT;
    return Bitmap.createScaledBitmap(b, newWidth, newHeight,  true);
}

This link provided the clue: difference between methods to scale a bitmap

Community
  • 1
  • 1
Ritesh
  • 11
  • 2
0

Worked for me, see this. But I have to say, I think SQLite is doing it right, and the android drawable is incorrectly sized.

Community
  • 1
  • 1
user426364
  • 160
  • 9
0

Use decodeByteArray(byte[] data, int offset, int length, BitmapFactory.Options opts) and in opts set inDesity to let say 160.

Mikooos
  • 5,360
  • 5
  • 31
  • 45
  • Thanks for the response, but this didn't work. I then set the inDensity to the actual screen density but that didn't make any difference either. This is what I did: DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); BitmapFactory.Options options = new BitmapFactory.Options(); options.inDensity = metrics.densityDpi; Bitmap bitmap = BitmapFactory.decodeByteArray(bb, 0, bb.length, options); – Ritesh Aug 15 '11 at 05:20
  • inDensity means what is the density of image, so it should be in this case 160, not depending on screen dpi. Depending on screen density is outDensity. So correct way is: BitmapFactory.Options options = new BitmapFactory.Options(); options.inDensity = 160; – Mikooos Aug 15 '11 at 09:21