避免从Android相机旋转两次位图

时间:2016-01-25 11:52:46

标签: android bitmap android-camera

目前我有代码:

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方法中的任何行。

1 个答案:

答案 0 :(得分:0)

在你的情况下,我会冻结' 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;
        }
    }