Makalele February 2016

Tranform orginal bitmap on 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?

Answers


meynety February 2016

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);
     

Post Status

Asked in February 2016
Viewed 3,996 times
Voted 4
Answered 1 times

Search




Leave an answer