Wednesday, 9 January 2019

View gets cropped above 10.000 pixel width

I'm having a SurfaceView inside a FrameLayout. The SurfaceView usually displays a video, for example purposes I'm actually drawing an image. The problem is, if I'm setting the size of the FrameLayout (or the SurfaceView) above 10.000 pixels in width, it gets cropped on the left side.

Tested on Android 7.1.1 (on a device and Emulator: Android TV (1080p) API 25

public class TestActivity extends Activity {    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //add framelayout
        FrameLayout backgroundFrame = new FrameLayout(this);
        setContentView(backgroundFrame);

        //add surfaceview
        TestSurfaceView testSurfaceView = new TestSurfaceView(this);
        backgroundFrame.addView(testSurfaceView);

        //resize
        FrameLayout.LayoutParams bgParams = (FrameLayout.LayoutParams) backgroundFrame.getLayoutParams();
        bgParams.width = 1920;
        bgParams.height = (int)Math.floor(bgParams.width * (9d/16d)); //16:9

        backgroundFrame.setX(0); //doesnt help
    }
}


public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder)
    {
        //load bitmap from file
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/testimg.png", options);

        Canvas c = surfaceHolder.lockCanvas();
        Rect rect = new Rect();
        rect.set(0,0, 1920, 1080); //image size

        Rect destRect = new Rect();
        destRect.set(0, 0, this.getWidth(), this.getHeight());

        //draw the image on the surface
        c.drawBitmap(bitmap, rect, destRect, null);
        surfaceHolder.unlockCanvasAndPost(c);
    }
}

The code above produces following output, which is correct.

1920px Test If I change the bgParams.width to 9600 - it scales up correctly and still displays starting from the left edge of the image:

9600px Test

But if I change the code to e.g. 10050, the image gets cropped by 50 pixels to the left.

10050px test

If I set:

destRect.set(50, 0, this.getWidth(), this.getHeight());

10050px test with pos 50px of image It gets displayed correctly, but as I can't do that for the MediaPlayer and it's super weird, I'm trying to find a good solution.

I also tried setting the sizes directly on the SurfaceView and instead of changing the LayoutParams, I tried setting scaleX and scaleY of the Framelayout but ended up with the same results.

(btw. opengl max texture size is about 16000px - setting it above the ~16000px results in a black screen and an exception, so that is not the cause of the problem)



from View gets cropped above 10.000 pixel width

No comments:

Post a Comment