1

I have two images and I want to set one upon another.

However after merging I get low quality file.

This is my original topImage (96x96) pixels:

enter image description here

This is my bottomIamge (74x74) pixels:

enter image description here

You can see that quality is pretty good.

When I run under mentioned code I get merged Image (74x74):

enter image description here

Now you can see that topImage lost his quality.

Here is relevant code:

        // load bottom image from assets: 
        InputStream is;
        Bitmap bottomImage;
        try {
            is = context.getAssets().open("images/avatar1.png");
        } catch (IOException e1) {
            int resID = context.getResources().getIdentifier("unknown_item", "drawable", context.getPackageName());
            is = context.getResources().openRawResource(resID);
        }

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inMutable = true;

        bottomImage = BitmapFactory.decodeStream(is,null,options);
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }

 Bitmap topImage = null;

 String base64Img = null;

// get byte array from String (base64).   
byte[] backToBytes = Base64.decode(base64Img, Base64.DEFAULT);
// here I verified that image I got from byte array still has good quality          
//writeToStorage(backToBytes, "test.png");

 // create Bitmap       
 topImage = BitmapFactory.decodeByteArray(backToBytes, 0, backToBytes.length, null);

// scale the image 
topImage = Bitmap.createScaledBitmap(topImage, 74, 74, false); // set fixed size 74x74 image
topImage = Bitmap.createBitmap(topImage, topImage.getWidth()/4, 0, topImage.getWidth()/2, topImage.getHeight());        

// shift it:
 Canvas comboImage = new Canvas(bottomImage);
// Then draw the second on top of that
comboImage.drawBitmap(topImage, 0f, 0f, null);


 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 bottomImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
 byte[] byteArray = stream.toByteArray();
 String base64String = Base64.encodeToString(byteArray, Base64.DEFAULT);

If I'll draw base64String I get merged Image

Do I miss something?

Does Bitmap.createScaledBitmap(topImage, 37, 74, false); scales to 37x74 pixels?

Thanks,

snaggs
  • 5,543
  • 17
  • 64
  • 127

2 Answers2

1

For now I use this way (based on THIS answer):

// this method should replace Bitmap.createScaledBitmap
private Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight){
        Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);

        float ratioX = newWidth / (float) bitmap.getWidth();
        float ratioY = newHeight / (float) bitmap.getHeight();
        float middleX = newWidth / 2.0f;
        float middleY = newHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bitmap, middleX - bitmap.getWidth() / 2, middleY - bitmap.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }

And now I can replace:

topImage = Bitmap.createScaledBitmap(topImage, 74, 74, false);

with:

topImage = scaleBitmap(topImage, 74, 74);

was:

enter image description here

now:

enter image description here

Its not the same quality but seems better

Community
  • 1
  • 1
snaggs
  • 5,543
  • 17
  • 64
  • 127
  • You will get the same effect with createScaledBitmap, if you change last parameter to true. And you really should watch the video I suggested to you. – Ilya Gazman Jul 02 '14 at 20:09
0

You cannot keep the quality when scaling by not hall number(2,3,4,5). In your case you are scaling 96 pixels to 74.

You can either change the scale to 48 pixels(x2) or keep it 96 pixels.

Also watch this video that explain what is anti-aliacing, and how it can help you.

Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
  • THe idea is that `topImage` might be different size, 120x120, 56x56 ... But I want to put it on `bottomImage` that has fixed 74x74. Thanks, – snaggs Jul 02 '14 at 18:54
  • Well as I explained. You are going to have pixillation problems if you scale by not hall number. – Ilya Gazman Jul 02 '14 at 19:05
  • Sorry, but this answer doesn't satisfy me because from your words I can't do what I want. Anyways I found several solutions that guarantee not the same quality but close to. Thank you again – snaggs Jul 02 '14 at 19:35
  • @fessy share it with us, so we will all know. – Ilya Gazman Jul 02 '14 at 19:39