2011-12-08 15 views
9

Đây là một biến thể về một câu hỏi thường được hỏi nhưng tôi không thấy tình huống chính xác này, vì vậy tôi sẽ ném nó ra khỏi đó.Làm thế nào để thay đổi hướng của bộ đệm gọi lại xem trước của máy ảnh?

Tôi đã thiết lập gọi lại onPreviewFrame. Điều này nhận được một byte [] với dữ liệu NV21 trong đó. Chúng tôi mã hóa nó và gửi nó ra dưới dạng luồng video. Ở phía bên kia, chúng tôi thấy video bị lệch, 90 hoặc 270 độ, tùy thuộc vào điện thoại.

Câu hỏi là, cách xoay dữ liệu, không chỉ hình ảnh xem trước? Camera.Parameters.setRotation chỉ ảnh hưởng đến việc chụp ảnh chứ không ảnh hưởng đến video. Camera.setDisplayOrientation đặc biệt cho biết nó chỉ ảnh hưởng đến bản xem trước hiển thị, không ảnh hưởng đến khung byte:

Điều này không ảnh hưởng đến thứ tự mảng byte được truyền trong onPreviewFrame (byte [], Camera), ảnh JPEG hoặc video đã ghi.

Vậy có cách nào, ở bất kỳ cấp API nào, để thay đổi hướng của mảng byte không? Không có điều đó, bạn thậm chí có thể xoay NV21 (YVU) định dạng mà điều này đi vào, hoặc tôi cần phải RGB nó đầu tiên?

+2

Có lẽ tôi là thiếu một cái gì đó, nhưng không phải là nó là một nhiệm vụ phía trước tương đối thẳng của chạy dữ liệu thông qua một ma trận để xoay nó theo bất cứ cách nào bạn muốn? Có lẽ bạn biết chiều rộng và chiều cao của bản xem trước của bạn, vì vậy, bạn sẽ có thể chỉ cần sao chép các byte vào một mảng byte mới có chúng được sắp xếp theo hướng mong muốn, không? Tôi đã không làm điều này, vì vậy, có lẽ tôi là woefully tắt cơ sở. –

+0

Không, điều đó sẽ làm điều đó, nhưng để làm điều này cho mỗi khung hình, ngay cả nói 5ps, có vẻ như rất nhiều chế biến. Nhưng tôi nghĩ đó có thể là cách duy nhất. – Hieronymus

Trả lời

1

Tắt bạn cần tự xoay từng khung hình trước khi gửi đi. Chúng tôi đã kết thúc bằng libyuv, trong đó có một chức năng rất thuận tiện mà cả hai quay và chuyển đổi nó - libyuv :: ConvertToI420

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

0

Tôi nghĩ rằng bạn sẽ cần tự xoay hình ảnh. Tôi đã làm nó một lần bằng cách sử dụng NDK và thư viện leptonica. Nhìn vào mã của tôi sẽ giúp bạn bắt đầu. Hiệu suất là okay trên một Samsung Galaxy S2 (tôi nghĩ rằng tôi có khoảng 15 khung hình hoặc hơn). Kể từ khi tôi đã đẩy kết quả vào một kết cấu openGL tôi đã phải cũng swizzle byte màu xung quanh .. Bạn có thể tăng tốc độ nó bằng cách xoay hình ảnh trực tiếp trong vòng lặp mà giải mã dữ liệu yuv ..

mPix32 và mPix8 là trước đây được phân bổ để giữ dữ liệu được chuyển đổi.Bạn sẽ cần phải thay thế bằng cấu trúc dữ liệu hình ảnh của riêng bạn tất nhiên ..

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); 

} 
Các vấn đề liên quan