Search code examples
androidmatrixscaleandroid-animationandroid-view

Stretch/Scale a Specific Region of View/Bitmap


I am trying to apply a ScaleAnimation to a View, but I have a somewhat nontraditional requirement: I would like to scale only a very specific region of the View.

Using the existing ScaleAnimation class I can easily uniformly scale a view. I can also set a pivot point about which to scale a view. Below is an example of that:

smiley scaled from bottom

This is straightforward. But I wish to achieve the following, which results from scaling only a particular region of a view (or in this case a small horizontal rectangle in the middle of the smiley):

smiley with specific region scaled

I dug around the source code for ScaleAnimation, and the following function seems to be responsible for scaling:

protected void applyTransformation(float interpolatedTime, Transformation t) {
    float sx = 1.0f;
    float sy = 1.0f;

    if (mFromX != 1.0f || mToX != 1.0f) {
        sx = mFromX + ((mToX - mFromX) * interpolatedTime);
    }
    if (mFromY != 1.0f || mToY != 1.0f) {
        sy = mFromY + ((mToY - mFromY) * interpolatedTime);
    }

    if (mPivotX == 0 && mPivotY == 0) {
        t.getMatrix().setScale(sx, sy);
    } else {
        t.getMatrix().setScale(sx, sy, mPivotX, mPivotY);
    }
}

Since this function is simply applying a scale operation to a matrix, I was thinking there is some sort of matrix operation that I could use to write a custom scale animation, but my linear algebra know-how is lacking. The solution to this may be far simpler as it seems as though others would run into this issue, but I haven't been able to find any solutions. Thanks in advance.


Solution

  • A matrix transforms the entire bitmap. You can not scale regions with a single matrix.