Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何更改相机预览回调缓冲区的方向?_Android_Android Camera - Fatal编程技术网

Android 如何更改相机预览回调缓冲区的方向?

Android 如何更改相机预览回调缓冲区的方向?,android,android-camera,Android,Android Camera,这是一个在这里经常被问到的问题的变体,但我看不出确切的情况,所以我会把它扔出去 我已设置onPreviewFrame回调。这将获取一个包含NV21数据的字节[]。我们使用h.264编码并将其作为视频流发送出去。另一方面,我们看到视频倾斜,90度或270度,取决于手机 所以问题是,如何旋转数据,而不仅仅是预览图像?Camera.Parameters.setRotation仅影响拍照,而不影响视频。Camera.setDisplayOrientation特别指出,它只影响显示预览,而不影响帧字节:

这是一个在这里经常被问到的问题的变体,但我看不出确切的情况,所以我会把它扔出去

我已设置onPreviewFrame回调。这将获取一个包含NV21数据的字节[]。我们使用h.264编码并将其作为视频流发送出去。另一方面,我们看到视频倾斜,90度或270度,取决于手机

所以问题是,如何旋转数据,而不仅仅是预览图像?Camera.Parameters.setRotation仅影响拍照,而不影响视频。Camera.setDisplayOrientation特别指出,它只影响显示预览,而不影响帧字节:

这不会影响在预览帧(字节[],照相机)、JPEG图片或录制的视频中传递的字节数组的顺序


那么,在任何API级别,有没有一种方法可以改变字节数组的方向呢?如果不行,你甚至可以旋转这张图片的NV21(YVU)格式,或者我需要先对其进行RGB吗?

我想你需要自己旋转图片。我曾经用NDK和leptonica库做过一次。看看我的代码,你就可以开始了。在三星Galaxy S2上的表现还算不错(我想大概有15帧左右)。由于我将结果推送到openGL纹理中,所以我还必须快速旋转颜色字节。。 你可以通过直接在解码yuv数据的循环中旋转图像来加快速度

mPix32和mPix8以前分配用于保存转换后的数据。当然,您需要使用自己的映像数据结构进行替换

jint Java_de_renard_ImageFilter_nativeProcessImage(JNIEnv *env, jobject javathis, jbyteArray frame) {
    ....
    jbyte *data_buffer = env->GetByteArrayElements(frame, NULL);
    l_uint8 *byte_buffer = (l_uint8 *) data_buffer;
    yuvToPixFast(byte_buffer, mPix32, mPix8);
    env->ReleaseByteArrayElements(frame, data_buffer, JNI_ABORT);
    ....
}

static inline void yuvToPixFast(unsigned char* pY, Pix* pix32, Pix* pix8) {
    int i, j;
    int nR, nG, nB;
    int nY, nU, nV;
    l_uint32* data = pixGetData(pix32);
    l_uint32* data8 = pixGetData(pix8);
    l_int32 height = pixGetHeight(pix32);
    l_int32 width = pixGetWidth(pix32);
    l_int32 wpl = pixGetWpl(pix32);
    l_int32 wpl8 = pixGetWpl(pix8);
    l_uint8 **lineptrs = pixSetupByteProcessing(pix8, NULL, NULL);
    l_uint8* line8;

    //memcpy(data8,pY,height*width);

    unsigned char* pUV = pY + width * height;

    for (i = 0; i < height; i++) {
        nU = 0;
        nV = 0;
        unsigned char* uvp = pUV + (i >> 1) * width;
        line8 = lineptrs[i];
        memcpy(line8, pY, wpl8 * 4);

        for (j = 0; j < width; j++) {

            if ((j & 1) == 0) {
                nV = (0xff & *uvp++) - 128;
                nU = (0xff & *uvp++) - 128;
            }
            // Yuv Convert
            nY = *(pY++);
            //*line8++ = (l_uint8) nY;
            nY -= -16;

            if (nY < 0) {
                nY = 0;
            }
            int y1192 = nY * 1192;

            /*double saturation to increase cartoon effect*/
            //nU<<=1;
            //nV<<=1;

            nB = y1192 + 2066 * nU;
            nG = y1192 - 833 * nV - 400 * nU;
            nR = y1192 + 1634 * nV;

            if (nR < 0) {
                nR = 0;
            } else if (nR > 262143) {
                nR = 262143;
            }
            if (nG < 0) {
                nG = 0;
            } else if (nG > 262143) {
                nG = 262143;
            }
            if (nB < 0) {
                nB = 0;
            } else if (nB > 262143) {
                nB = 262143;
            }
            //RGBA
            //ABGR
            *data++ = ((nR << 14) & 0xff000000) | ((nG << 6) & 0xff0000) | ((nB >> 2) & 0xff00) | (0xff);
            //*data++ = (0x00 << 24) | (0xff<<16) | (0x00<<8) | ( 0xff) ;
            //*data++ = (0xff << 24) | ((nB << 6) & 0xff0000) | ((nG >> 2) & 0xff00) | ((nR >> 10) & 0xff);
        }
    }
    pixCleanupByteProcessing(pix8, lineptrs);

}
jint Java_de_renard_ImageFilter_nativeProcessImage(JNIEnv*env、jobject javathis、jbyterarray frame){
....
jbyte*data\u buffer=env->GetByteArrayElements(帧,空);
l_uint8*字节缓冲区=(l_uint8*)数据缓冲区;
yuvToPixFast(字节缓冲区,mPix32,mPix8);
环境->ReleaseByteArrayElements(帧、数据缓冲区、JNI\U中止);
....
}
静态内联void yuvToPixFast(无符号字符*pY,Pix*pix32,Pix*pix8){
int i,j;
国际天然气、天然气、天然气;
内华达州新南威尔士州内特;
l_uint32*data=pixGetData(pix32);
l_uint32*data8=pixGetData(pix8);
l_int32高度=pixGetHeight(pix32);
l_int32 width=pixGetWidth(pix32);
l_int32 wpl=pixGetWpl(pix32);
l_int32 wpl8=pixGetWpl(pix8);
l_uint8**lineptrs=pixSetupByteProcessing(pix8,NULL,NULL);
l_uint8*第8行;
//memcpy(数据8,pY,高度*宽度);
无符号字符*pUV=pY+宽度*高度;
对于(i=0;i>1)*宽度;
line8=lineptrs[i];
memcpy(第8行,pY,wpl8*4);
对于(j=0;j//nU结果表明,在发送每个帧之前,您确实需要自己旋转每个帧。我们最终使用了libyuv,它有一个非常方便的函数,可以旋转和转换它-libyuv::ConvertToI420


也许我遗漏了一些东西,但这不是一个相对简单的任务,通过矩阵运行数据,以任意方式旋转它吗?大概你知道预览的宽度和高度,所以,你应该能够将字节复制到一个新的字节数组中,并按所需的方向排序,不是吗?我知道了没有这样做,所以,也许我有点太离谱了。不,这样就可以了,但对每一帧都这样做,即使是5ps,似乎需要很多处理。但我认为这可能是唯一的方法。