Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transform original bitmap on android

Tags:

android

So, I'm using this library https://github.com/thuytrinh/android-collage-views to add "MultiTouchListener" feature to my ImageView. Basically I let user to modify a photo to his needs using rotation, scale and translation. Now the only problem is how to save it. I did it like this:

    Bitmap bitmap = Bitmap.createBitmap(imageContainer.getWidth(), imageContainer.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawColor(Color.WHITE);
    imageContainer.draw(canvas);

It works, but image is not big enough - it's as big as view on phone so it depends on screen resolution. And I want to "apply" these transformations on given bitmap with full size. And I want transformed image to look like on screen (so it'll need to crop everything out of screen)

I tried the following:

    Bitmap newBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(newBitmap);
    canvas.drawColor(Color.WHITE);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    canvas.drawBitmap(image, imageView.getMatrix(), paint);

But it doesn't look as expected.

User screen:

enter image description here

And output image (without cropping, because I don't want which side I should crop):

enter image description here

How can I fix this? Is there any solution?

like image 999
Makalele Avatar asked Sep 25 '22 10:09

Makalele


1 Answers

Here is one way to do it, definitely not perfect but should give you a good start :

In this, container refers to the view that contains the transformed ImageView, the phone case on your screenshot and src the raw source bitmap.

  • First, you need to compute the desired width and height of the output bitmap, i.e the size it would be to make the image fit in it while keeping the ratio of the container :

    float containerWidth = containerView.getWidth();
    float containerHeight = containerView.getHeight();
    
    float srcWidth = src.getWidth();
    float srcHeight = src.getHeight();
    
    float containerRatio = containerWidth / containerHeight;
    float srcRatio = srcWidth / srcHeight;
    
    float outputWidth, outputHeight;
    
    if(srcRatio > containerRatio) { //fits in width
            outputWidth = srcWidth;
            outputHeight = srcWidth / containerRatio;
    }
    else if(srcRatio < containerRatio) { //fits in height
            outputHeight = srcHeight;
            outputWidth = srcHeight * containerRatio;
    }
    else {
        outputWidth = srcWidth;
        outputHeight = srcHeight;
    }
    
  • Apply the ratio between container width/height and output width/height to the translation part of the matrix that hold the transformation that the user did

    float containerToOutputRatioWidth = outputWidth / containerWidth;
    float containerToOutputRatioHeight = outputHeight / containerHeight;
    
    float[] values = new float[9];
    transformedImageView.getMatrix().getValues(values);
    values[2] = values[2] * containerToOutputRatioWidth;
    values[5] = values[5] * containerToOutputRatioHeight;
    Matrix outputMatrix = new Matrix();
    outputMatrix.setValues(values);
    
  • Draw the output bitmap as you were doing with the correct size (outputWidth, outputHeight) and matrix (outputMatrix).

    Bitmap newBitmap = Bitmap.createBitmap(Math.round(outputWidth), Math.round(outputHeight), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(newBitmap);
    canvas.drawColor(Color.WHITE);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    canvas.drawBitmap(src, outputMatrix, paint);
    

Demo.

Warnings

You should be careful about memory allocation, this code will lead to allocate some massive bitmaps, you should implement some kind of limit that get along with your needs. (Also do allocation and drawing in background)

You might need to do some adjustment depending on where you place the image in the first place.

like image 100
meynety Avatar answered Oct 11 '22 07:10

meynety