2015-08-06 8 views
3

Я хочу повернуть изображение YUV420SP на 90 против часовой стрелки. Размер изображения составляет 640 * 480, поэтому размер поворачиваемого изображения становится 480 * 640, который мне не нужен. Поэтому я хочу извлечь данные 480 * 480 (или любой другой квадратный размер) и повернуть эти данные.Поверните изображение YUV420Sp на 90 градусов против часовой стрелки

Я видел: Rotate an YUV byte array on Android

Но этот ответ поворачивается на 90 по часовой стрелке.

Может кто-нибудь предложить функцию, которая поворачивает данные YUV420Sp на 90 (против часовой стрелки) или на 270 градусов (по часовой стрелке) без изменения размеров изображения.

+0

Я решил это в моем android, но это в собственном коде, который я использую через JNI. Вы хотите увидеть решение на C++ или хотите только Java? – spartygw

+0

Мне нужен собственный код, можете ли вы написать свой код здесь. благодаря – nkalra0123

ответ

4

ОК, вот мой родной код, который развился после многих ударов головы.

Моя трудность заключалась в том, что я не понимаю, планарные форматы изображений, пока я не увидел this и это:

YUV420SP NV21 image format

Вот 2 функции я в конце концов написал:

// rotate luma image plane 90* 
// 
//    (dst direction) 
//     ------> 
//  dst -> +-------------+ 
//    |^   | 
//    |^ (base dir) | 
//    |^   | 
//  base -> +-------------+ <- endp 
// 
////////////////////////////////////////////////////////// 
void rotateLumaPlane90(const unsigned char *src, unsigned char *dst, 
         size_t size, size_t width, size_t height) 
{ 
    const unsigned char *endp; 
    const unsigned char *base; 
    int j; 

    endp = src + size; 
    for (base = endp - width; base < endp; base++) { 
     src = base; 
     for (j = 0; j < height; j++, src -= width) 
     { 
      *dst++ = *src; 
     } 

    } 
} 


// 
// nv12 chroma plane is interleaved chroma values that map 
// from one pair of chroma to 4 pixels: 
// 
// Y1 Y2 Y3 Y4 
// Y5 Y6 Y7 Y8 U1,V1 -> chroma values for block Y1 Y2 
// Y9 Ya Yb Yc          Y5 Y6 
// Yd Ye Yf Yg 
// ----------- U2,V2 -> chroma values for block Y3 Y4 
// U1 V1 U2 V2          Y7 Y8 
// U3 V3 U4 V4 
// 
////////////////////////////////////////////////////////// 
void rotateChromaPlane90(const unsigned char *src, unsigned char *dst, 
         size_t size, size_t width, size_t height) 
{ 
    // src will start at upper right, moving down to bottom 
    // then left 1 col and down... 
    // 
    // dest will start at end and go to 0 

    int row = 0; 
    int col = (int) width; 
    int src_offset = col - 1; 
    int dst_offset = (int) size - 2; 

    while (src_offset >= 0) 
    { 
     dst[dst_offset] = src[src_offset]; 
     dst[dst_offset+1] = src[src_offset+1]; 
     dst_offset -= 2; 

     src_offset += width; 
     row++; 

     if (row >= height) { 
      col -= 2; 
      src_offset = col; 
      row = 0; 
     } 
    } 
} 

И здесь является примером того, как я называю эти функции с родной от orroid:

// first rotate the Y plane 
    rotateLumaPlane90((unsigned char *) encode_buffer, 
        rotate_buffer, 
        yPlaneSize, 
        gInputWidth, 
        gInputHeight); 


    // now rotate the U and V planes 
    rotateChromaPlane90((unsigned char *) encode_buffer + yPlaneSize, 
         rotate_buffer + yPlaneSize, 
         yPlaneSize/2, 
         gInputWidth, 
         gInputHeight/2); 

Обратите внимание, что последний параметр для rotateChromaPlane90 - высота оригинального изображения/2. Я должен, вероятно, просто изменить функцию поворота цветности, чтобы сделать это менее подверженным ошибкам.

Когда переворачивается на спину перед камерой, то я обнаружил, что мне нужно, чтобы повернуть 90 * в противоположном направлении (или 270 *), поэтому у меня есть 270 * изменение в качестве:

// rotate luma image plane 270* 
// 
//    +-------------+ 
//    |^   | 
//    |^ (base dir) | 
//    |^   | 
//  base -> +-------------+ <- endp 
//      ^
//    <---------- | 
//    (dst dir) dst 
// 
////////////////////////////////////////////////////////// 
void rotateLumaPlane270(unsigned char *src, 
         register unsigned char *dst, 
         int size, int width, int height) 
{ 
    unsigned char *endp; 
    register unsigned char *base; 
    int j; 

    endp = src + size; 
    dst = dst + size - 1; 
    for (base = endp - width; base < endp; base++) { 
     src = base; 
     for (j = 0; j < height; j++, src -= width) 
     { 
      *dst-- = *src; 
     } 

    } 
} 

// 
// nv21 chroma plane is interleaved chroma values that map 
// from one pair of chroma to 4 pixels: 
// 
// Y1 Y2 Y3 Y4 
// Y5 Y6 Y7 Y8 U1,V1 -> chroma values for block Y1 Y2 
// Y9 Ya Yb Yc          Y5 Y6 
// Yd Ye Yf Yg 
// ----------- U2,V2 -> chroma values for block Y3 Y4 
// U1 V1 U2 V2          Y7 Y8 
// U3 V3 U4 V4 
// 
////////////////////////////////////////////////////////// 
void rotateChromaPlane270(unsigned char *src, 
          register unsigned char *dst, 
          int size, int width, int height) 
{ 
    // src will start at upper right, moving down to bottom 
    // then left 1 col and down... 
    // 
    // dest will start at 0 and go til end 

    int row = 0; 
    int col = width; 
    int src_offset = col - 1; 
    int dst_offset = 0; 

    while (src_offset > 0) 
    { 
     dst[dst_offset++] = src[src_offset]; 
     dst[dst_offset++] = src[src_offset+1]; 

     src_offset += width; 
     row++; 

     if (row >= height) { 
     col -= 2; 
     src_offset = col; 
     row = 0; 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^