Как изменить ориентацию буфера обратного вызова предварительного просмотра камеры? - PullRequest
9 голосов
/ 08 декабря 2011

Это вариант вопроса, который часто задают здесь, но я не вижу точной ситуации, поэтому я добавлю его.

У меня настроен обратный вызов onPreviewFrame.Получается байт [] с данными NV21.Мы кодируем его в формате h.264 и отправляем как видеопоток.С другой стороны, мы видим перекошенное видео на 90 или 270 градусов, в зависимости от телефона.

Поэтому вопрос заключается в том, как повернуть данные , а не только предварительное изображение.?Camera.Parameters.setRotation влияет только на съемку, а не на видео.Camera.setDisplayOrientation, в частности, говорит, что влияет только на предварительный просмотр отображения, а не на байты кадра:

Это не влияет на порядок байтового массива, передаваемого в onPreviewFrame (byte [], Camera), изображениях JPEG илизаписанные видео.

Так есть ли способ на любом уровне API изменить ориентацию массива байтов?Если это не удастся, вы можете даже повернуть формат NV21 (YVU), в который это входит, или мне сначала нужно его RGB?

Ответы [ 2 ]

1 голос
/ 04 июня 2014

Оказывается, вам нужно повернуть каждый кадр самостоятельно перед его отправкой.В итоге мы использовали libyuv, которая имеет очень удобную функцию, которая вращает и конвертирует ее - libyuv :: ConvertToI420

https://code.google.com/p/libyuv/

0 голосов
/ 25 марта 2012

Я думаю, что вам нужно повернуть картинку самостоятельно. Я сделал это однажды, используя NDK и библиотеку leptonica. Посмотрите на мой код, чтобы вы начали. Производительность была хорошей на Samsung 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);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...