【问题标题】:Avoid rotating bitmap twice from Android camera避免从 Android 相机旋转位图两次
【发布时间】:2016-01-25 11:52:46
【问题描述】:

目前我有代码:

onPreviewFrame(byte[] 数据)

            int[] rgbs = new int[480*800];
            decodeYUV(rgbs, data, 480, 800);
            Bitmap bitmap = Bitmap.createBitmap(rgbs, 800, 480, Bitmap.Config.ARGB_8888);
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap,800,480,true);
            Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);

            sbut.setImageBitmap(rotatedBitmap);

decodeYUV 函数所在的位置here

预览是这样设置的:

    param.setPreviewSize(800, 480);
    camera.setDisplayOrientation(90);

所以预览设置为纵向模式,Height = 800, Width = 480

我最终不得不回到横向来执行转换。然后再次旋转回纵向。我可以想象这很慢。没有双重旋转有没有更有效的替代方案?

我想保持纵向模式的预览。我的最终结果应该是上面的rotatedBitmap,这只是肖像。 onPreviewFrame 方法中的任何行都可以更改。

【问题讨论】:

    标签: android bitmap android-camera


    【解决方案1】:

    在你的情况下,我会在 Potrait 模式下“冻结”Activity,并使用重力传感器在没有 Activity 或相机重新创建的情况下检查旋转。

    冻结使用这个:

    this.setRequestedOrientation(
                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    

    要旋转,我使用以下代码:

    public static void rotateNV21(byte[] input, byte[] output, int width, int height, int rotation) {
            try{
            boolean swap = (rotation == 90 || rotation == 270);
            boolean yflip = (rotation == 90 || rotation == 180);
            boolean xflip = (rotation == 270 || rotation == 180);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    int xo = x, yo = y;
                    int w = width, h = height;
                    int xi = xo, yi = yo;
                    if (swap) {
                        xi = w * yo / h;
                        yi = h * xo / w;
                    }
                    if (yflip) {
                        yi = h - yi - 1;
                    }
                    if (xflip) {
                        xi = w - xi - 1;
                    }
                    output[w * yo + xo] = input[w * yi + xi];
                    int fs = w * h;
                    int qs = (fs >> 2);
                    xi = (xi >> 1);
                    yi = (yi >> 1);
                    xo = (xo >> 1);
                    yo = (yo >> 1);
                    w = (w >> 1);
                    h = (h >> 1);
                    // adjust for interleave here
                    int ui = fs + (w * yi + xi) * 2;
                    int uo = fs + (w * yo + xo) * 2;
                    // and here
                    int vi = ui + 1;
                    int vo = uo + 1;
                    output[uo] = input[ui]; 
                    output[vo] = input[vi]; 
                }
            }
            }catch (IndexOutOfBoundsException e){
                output = input;
            }
        }
    

    【讨论】:

    • 我希望它始终处于纵向模式。即旋转手机不应该有所作为。
    • 我的问题是,数据接收正确。但是要正确地将 YUV 转换为 RGB,我需要在横向模式下进行。然后我需要将其旋转回纵向。无论如何要进行纵向转换?
    • 这个新代码会让我的代码更有效率吗? T
    • @GregPeckory ,此代码可以帮助您将 YUV 数据旋转 90 度。
    • 我明白了,感谢您的帮助。但我的问题是因为我认为这没有必要。因为我的预览框架已经处于纵向模式,因此setDisplayOrientation(90)。为什么 YUV 转换不能保持纵向模式。为什么需要旋转到横向才能执行正确的转换?对不起,如果我没有多大意义
    猜你喜欢
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多