视图裁剪超过10.000像素宽度

时间:2019-01-07 12:07:10

标签: android surfaceview android-source android-7.0-nougat android-x86

  

更新:   在Android Oreo(8.X)的Emulator上运行。我有可能直接对android源进行更改,因此,如果有人知道我必须更改或更新以使其正常工作的android源中的内容,这也将有所帮助(因此,我实际上并不需要Android 7解决方法。虽然无法更新至Android 8。)

我在FrameLayout中有一个SurfaceView。 SurfaceView通常会显示视频,例如,我实际上是在绘制图像。 问题是,如果我将FrameLayout(或SurfaceView)的尺寸设置为宽度大于10.000像素,则会在左侧裁剪。

在Android 7.1.1上进行了测试(在设备和仿真器上:Android TV(1080p)API 25

public class TestActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //add surfaceview
        TestSurfaceView testSurfaceView = new TestSurfaceView(this);
        setContentView(testSurfaceView);

        //resize
        FrameLayout.LayoutParams bgParams = (FrameLayout.LayoutParams) testSurfaceView.getLayoutParams();

        //testcase full hd - working
        bgParams.width = 1920;

        //testcase 2 - working - each segment is 330px as 9900 / 1920 * 64 (default segment width) == 330
        //bgParams.width = 9900;

        //testcase 3 - working
        //bgParams.width = 10000;

        //testcase 4 - not working - each segment is 335px which is correct but first cell gets cropped by exactly 50px to the left
        //bgParams.width = 10050;

        bgParams.height = (int)Math.floor(bgParams.width * (9d/16d)); //16:9

        testSurfaceView.setX(0); //doesnt help

        /*
         Also the position counts into the 10000px limitation as you can see on following testcases
         */
        /*
        bgParams.width = 9900;
        bgParams.height = (int)Math.floor(bgParams.width * (9d/16d)); //16:9

        //works - as 9900 + 90 < 10000
        testSurfaceView.setX(90);

        //doesnt work, crops 50px to the left - 9900 + 150 -> 10050
        testSurfaceView.setX(150);
        */
    }
}

public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{

public TestSurfaceView(TestActivity context) {
    super(context);

    SurfaceHolder holder = this.getHolder();
    holder.addCallback(this);
}

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

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}
}

styles.xml-主题

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen">
        <!-- Customize your theme here. -->
    </style>

</resources>

上面的代码会产生以下输出,这是正确的。

1920px Test 如果我将bgParams.width更改为9600-它会正确放大,并且仍然从图像的左边缘开始显示:

9600px Test

但是如果我将代码更改为10050,图像向左裁剪50个像素。

10050px test

如果我设置了

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

10050px test with pos 50px of image 它可以正确显示,但是由于MediaPlayer无法做到这一点,而且它非常怪异,因此我试图找到一个好的解决方案。

我还尝试直接在SurfaceView上设置尺寸,而不是更改LayoutParams,而是尝试设置Framelayout的scaleX和scaleY,但最终得到了相同的结果。

(请注意,opengl的最大纹理大小约为16000px-将其设置为〜16000px以上会导致黑屏和异常,因此不是问题的原因)

更新: 发表所有来源。无论如何,这是完整的android studio项目: WeTransfer project download link

0 个答案:

没有答案