Search code examples
javaandroidmatrixvideocrop

Video cropping w/ Matrix android java


The task is to crop video by given points(like rectangle) and display the cropped video.
The code works with cropping the first halh of video(0, 0, videoWidth/2, videoHeight). But when i tryed to display the second one(videoWidth/2, 0, videoWidth, videoHeight), that is what was displayed.

The video is displayed on TextureView inside FrameLayout.

The part, that doesn't work:

private void updateTextureViewSize(int ax, int ay, int bx, int by) {
    float scaleX;
    float scaleY;

    //proportions between screen and frame dimensions
    scaleX = mVideoWidth / mDisplayWidth;
    scaleY = mVideoHeight / mDisplayHeight;

    float scaleRegionW = mVideoWidth / Math.abs(ax - bx);
    float scaleRegionH = mVideoHeight / Math.abs(ay - by);
    float scaleRegion = scaleRegionW < scaleRegionH ? scaleRegionW : scaleRegionH;

    Matrix matrix = new Matrix();
    if (scaleX > scaleY) {
        matrix.setScale(scaleRegion / scaleY, scaleRegion);
        matrix.postTranslate(-ax * (int) scaleRegion / scaleY, -ay * scaleRegion / scaleY);
    } else {
        matrix.setScale(scaleRegion, scaleRegion / scaleX);
        matrix.postTranslate(-ax * scaleRegion / scaleX, -ay * scaleRegion / scaleX);
    }
    mTextureView.setTransform(matrix);
    mTextureView.setLayoutParams(new FrameLayout.LayoutParams((int) mDisplayWidth, (int) mDisplayHeight));
}

Solution

  • The answer was found by Dmitry Yacenko. The full code.

    An easy way to crop video by given points (ax, ay, bx, xy) is:

        float scaleX = mDisplayWidth / mVideoWidth, scaleY = mDisplayHeight / mVideoHeight; 
        //proportions between screen and frame dimensions
        float scale = mDisplayHeight / Math.abs(by - ay);
        Matrix matrix = new Matrix();
        matrix.reset();
        matrix.setScale(scale / scaleX, scale / scaleY);
        //scaling video
        matrix.postTranslate(-scale * ax, -scale * ay);
        //move video, so the needed part of it will be displayed properly
        mTextureView.setLayoutParams(new FrameLayout.LayoutParams((int) mDisplayWidth, (int) mDisplayHeight));
        mTextureView.setTransform(matrix);
        //updating the Texture view