避免从Android摄像头旋转位图两次

避免从Android摄像头旋转位图两次,android,bitmap,android-camera,Android,Bitmap,Android Camera,目前我掌握了代码: onPreviewFrame(字节[]数据) 其中找到了decodeYUV功能 预览设置如下所示: param.setPreviewSize(800, 480); camera.setDisplayOrientation(90); 因此,预览设置为纵向模式,高度=800,宽度=480 我最终不得不回到景观来执行转换。然后再次旋转回“纵向”。我可以想象这是相当缓慢的。有没有一个没有双重轮换的更有效的替代方案 我想保持在肖像模式预览。我的最终结果应该是上面的ro

目前我掌握了代码:

onPreviewFrame(字节[]数据)

其中找到了
decodeYUV
功能

预览设置如下所示:

    param.setPreviewSize(800, 480);
    camera.setDisplayOrientation(90);
因此,预览设置为纵向模式,
高度=800,宽度=480

我最终不得不回到景观来执行转换。然后再次旋转回“纵向”。我可以想象这是相当缓慢的。有没有一个没有双重轮换的更有效的替代方案


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

在你的情况下,我会在Potrait模式下“冻结”活动,并使用重力传感器在没有活动或摄像机娱乐的情况下检查旋转

要冻结,请使用以下命令:

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;
        }
    }
publicstaticvoidrotatenv21(字节[]输入,字节[]输出,整数宽度,整数高度,整数旋转){
试一试{
布尔交换=(旋转==90 | |旋转==270);
布尔yflip=(旋转==90 | |旋转==180);
布尔xflip=(旋转==270 | |旋转==180);
对于(int x=0;x>2);
席=(席>1);
yi=(yi>>1);
xo=(xo>>1);
yo=(yo>>1);
w=(w>>1);
h=(h>>1);
//调整此处的交错
int ui=fs+(w*yi+xi)*2;
int uo=fs+(w*yo+xo)*2;
//这里呢
int vi=ui+1;
int vo=uo+1;
输出[uo]=输入[ui];
输出[vo]=输入[vi];
}
}
}catch(IndexOutOfBoundsException e){
输出=输入;
}
}

在你的情况下,我会在Potrait模式下“冻结”活动,并使用重力传感器在没有活动或摄像机娱乐的情况下检查旋转

要冻结,请使用以下命令:

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;
        }
    }
publicstaticvoidrotatenv21(字节[]输入,字节[]输出,整数宽度,整数高度,整数旋转){
试一试{
布尔交换=(旋转==90 | |旋转==270);
布尔yflip=(旋转==90 | |旋转==180);
布尔xflip=(旋转==270 | |旋转==180);
对于(int x=0;x>2);
席=(席>1);
yi=(yi>>1);
xo=(xo>>1);
yo=(yo>>1);
w=(w>>1);
h=(h>>1);
//调整此处的交错
int ui=fs+(w*yi+xi)*2;
int uo=fs+(w*yo+xo)*2;
//这里呢
int vi=ui+1;
int vo=uo+1;
输出[uo]=输入[ui];
输出[vo]=输入[vi];
}
}
}catch(IndexOutOfBoundsException e){
输出=输入;
}
}

我希望它始终处于纵向模式。i、 旋转手机不会有什么不同。我的问题是,数据接收正确。但要正确地将YUV转换为RGB,我需要在横向模式下进行。然后我需要把它旋转回肖像。还有其他方法可以在纵向转换吗?这个新代码会使我的代码更高效吗?T@GregPeckory,此代码可以帮助您将YUV数据旋转90度。我理解,并感谢您的帮助。但我的问题是因为我认为这不必要。因为我的预览帧已经处于纵向模式,所以设置了
setDisplayOrientation(90)
。为什么YUV转换不能将其保持在纵向模式。为什么需要旋转到横向以执行正确的转换?对不起,如果我没有做太多唤醒希望它总是在肖像模式。i、 旋转手机不会有什么不同。我的问题是,数据接收正确。但要正确地将YUV转换为RGB,我需要在横向模式下进行。然后我需要把它旋转回肖像。还有其他方法可以在纵向转换吗?这个新代码会使我的代码更高效吗?T@GregPeckory,此代码可以帮助您将YUV数据旋转90度。我理解,并感谢您的帮助。但我的问题是因为我认为这不必要。因为我的预览帧已经处于纵向模式,所以设置了
setDisplayOrientation(90)
。为什么YUV转换不能将其保持在纵向模式。为什么需要旋转到横向以执行正确的转换?对不起,我说的不太清楚