2014-10-28 1 views
1

이것은 이미지를 회전하는 데 사용한 코드입니다. 네트워크를 통해 보내야합니다. 이미지가 제대로 회전하고 있지만 이미지가 제대로 표시되지 않습니다. 이 코드는 cpp에서 네이티브로 작성했습니다. DecodeNV21() 3 개의 매개 변수 너비, 높이, 회전이 있습니다. 폭과 높이가 640,480입니다. 회전이 세로 인 경우 변수 회전은 1이고 높이와 너비는 640,480이됩니다. 회전은 가로 0입니다. 너비와 높이 640 및 480. 어느 누구도이 문제를 해결할 수 있도록 도와주세요. 해협 모드 회전은 정확합니다. 그러나 문제가있는 가로 모드입니다.안드로이드 카메라에서 NV21 이미지를 디코딩하지만 이미지의 색상이 올바르지 않습니다.

void DecodeNV21(int SrcHeight,int SrcWidth,int rotation) 
/* decodes NV21-encoded image data, which is the default camera preview image format. */ 
{ 
    //int SrcWidth = encoderContext.m_width; 
    //int SrcHeight = encoderContext.m_height; 
    int Rotate = rotation; 
    int Alpha = 0xFF; 
    int AlphaMask = Alpha << 24; 
/* Rotation involves accessing either the source or destination pixels in a 
    non-sequential fashion. Since the source is smaller, I figure it's less 
    cache-unfriendly to go jumping around that. */ 
    int DstWidth = (Rotate & 1) != 0 ? SrcHeight : SrcWidth; 
    int DstHeight = (Rotate & 1) != 0 ? SrcWidth : SrcHeight; 
    bool DecrementRow = Rotate > 1; 
    bool DecrementCol = Rotate == 1 || Rotate == 2; 
    int LumaRowStride = (Rotate & 1) != 0 ? 1 : SrcWidth; 
    int LumaColStride = (Rotate & 1) != 0 ? SrcWidth : 1; 
    int ChromaRowStride = (Rotate & 1) != 0 ? 2 : SrcWidth; 
    int ChromaColStride = (Rotate & 1) != 0 ? SrcWidth : 2; 
    // LOGME("DecodeNV21 decoding w:%d,h:%d,DecrementRow:%d,ChromaRowStride:%d, DecrementCol:%d,ChromaColStride:%d,LumaRowStride%d,LumaColStride:%d",DstWidth,DstHeight,DecrementRow,ChromaRowStride, DecrementCol,ChromaColStride,LumaRowStride,LumaColStride); 
    int dst = 0; 
    int i=0; 
    for (int row = DecrementRow ? DstHeight : 0;;) 
    { 
     if (row == (DecrementRow ? 0 : DstHeight)) 
      break; 
     if (DecrementRow) 
     { 
      --row; 
     } /*if*/ 
     for (int col = DecrementCol ? DstWidth : 0;;) 
     { 
      if (col == (DecrementCol ? 0 : DstWidth)) 
       break; 
      if (DecrementCol) 
      { 
       --col; 
      } /*if*/ 
      int Y = 0xff & (int)byte_array[row * LumaRowStride + col * LumaColStride]; /* [0 .. 255] */ 
     /* U/V data follows entire luminance block, downsampled to half luminance 
      resolution both horizontally and vertically */ 
     /* decoding follows algorithm shown at 
      <http://www.mail-archive.com/[email protected]/msg14558.html>, 
      except it gets red and blue the wrong way round */ 
      int Cr = 
       (0xff & (int)byte_array[SrcHeight * SrcWidth + row/2 * ChromaRowStride + col/2 * ChromaColStride]) - 128; 
       /* [-128 .. +127] */ 
      int Cb = 
       (0xff & (int)byte_array[SrcHeight * SrcWidth + row/2 * ChromaRowStride + col/2 * ChromaColStride + 1]) - 128; 
       /* [-128 .. +127] */ 
        int r,g,b; 
      int color = 
        AlphaMask 
       | 
         (r=max(
          min(
           (int)(
             Y 
            + 
             Cr 
            + 
             (Cr >> 1) 
            + 
             (Cr >> 2) 
            + 
             (Cr >> 6) 
           ), 
           255 
          ), 
          0 
         )) 
        << 
         16 /* red */ 
       | 
         (g=max(
          min(
           (int)(
             Y 
            - 
             (Cr >> 2) 
            + 
             (Cr >> 4) 
            + 
             (Cr >> 5) 
            - 
             (Cb >> 1) 
            + 
             (Cb >> 3) 
            + 
             (Cb >> 4) 
            + 
             (Cb >> 5) 
           ), 
           255 
          ), 
          0 
         )) 
        << 
         8 /* green */ 
       | (b=max(
         min(
          (int)(
            Y 
           + 
            Cb 
           + 
            (Cb >> 2) 
           + 
            (Cb >> 3) 
           + 
            (Cb >> 5) 
          ), 
          255 
         ), 
         0 
        )); /* blue */ 
         //color = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); 
      TypeConvert::udwordToBytes(color, encoderContext.m_in_Array_Encode,i * 4); 
     i++; 
      if (!DecrementCol) 
      { 
       ++col; 
      } /*if*/ 
     } /*for*/ 
     if (!DecrementRow) 
     { 
      ++row; 
     } /*if*/ 
    } /*for*/ 
} /*DecodeNV21*/ 
+0

내 질문이 저를 보자 취소되지 않은 경우 inform.I 나는이 코드를 시도했지만 내가 ("색상을 TypeConvert :: udwordToBytes을 사용하고 있기 때문에 넣어은 encoderContext있을 수있는을하지 않았다 –

답변

1

정말 기존의 코드를 정렬 할,하지만 단지 내 채택 솔루션을 붙여하지 마십시오 이미지 90, 180, 270도 및 수익을 회전 (... 내가 잊고 어딘가에서 그것을 가지고) 바이트 배열. 따라서 예를 들어, 세로 모드에서 카메라를 90도 회전하고 전면 카메라를 270도 회전시킬 수 있습니다. 비슷한 패턴에 따라 다른 회전 모드를 구현할 수 있습니다. 나는 당신이 그 길을 계속하기에 충분해야한다고 생각합니다.

private byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight) 
{ 

    byte [] yuv = new byte[imageWidth*imageHeight*3/2]; 
    // Rotate the Y luma 
    int i = 0; 
    for(int x = 0;x < imageWidth;x++) 
    { 
     for(int y = imageHeight-1;y >= 0;y--)        
     { 
      yuv[i] = data[y*imageWidth+x]; 
      i++; 
     } 

    } 
    // Rotate the U and V color components 
    i = imageWidth*imageHeight*3/2-1; 
    for(int x = imageWidth-1;x > 0;x=x-2) 
    { 
     for(int y = 0;y < imageHeight/2;y++)         
     { 
      yuv[i] = data[(imageWidth*imageHeight)+(y*imageWidth)+x]; 
      i--; 
      yuv[i] = data[(imageWidth*imageHeight)+(y*imageWidth)+(x-1)]; 
      i--; 
     } 
    } 
    return yuv; 
} 

private byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight) 
{ 
    byte [] yuv = new byte[imageWidth*imageHeight*3/2]; 
    int i = 0; 
    int count = 0; 

    for (i = imageWidth * imageHeight - 1; i >= 0; i--) { 
     yuv[count] = data[i]; 
     count++; 
    } 

    i = imageWidth * imageHeight * 3/2 - 1; 
    for (i = imageWidth * imageHeight * 3/2 - 1; i >= imageWidth 
      * imageHeight; i -= 2) { 
     yuv[count++] = data[i - 1]; 
     yuv[count++] = data[i]; 
    } 
    return yuv; 
} 

private byte[] rotateYUV420Degree270(byte[] data, int imageWidth, int imageHeight) 
{ 
    byte [] yuv = new byte[imageWidth*imageHeight*3/2]; 
    int nWidth = 0, nHeight = 0; 
    int wh = 0; 
    int uvHeight = 0; 
    if(imageWidth != nWidth || imageHeight != nHeight) 
    { 
     nWidth = imageWidth; 
     nHeight = imageHeight; 
     wh = imageWidth * imageHeight; 
     uvHeight = imageHeight >> 1;//uvHeight = height/2 
    } 

    //–˝◊™Y 
    int k = 0; 
    for(int i = 0; i < imageWidth; i++) { 
     int nPos = 0; 
     for(int j = 0; j < imageHeight; j++) { 
      yuv[k] = data[nPos + i]; 
      k++; 
      nPos += imageWidth; 
     } 
    } 

    for(int i = 0; i < imageWidth; i+=2){ 
     int nPos = wh; 
     for(int j = 0; j < uvHeight; j++) { 
      yuv[k] = data[nPos + i]; 
      yuv[k + 1] = data[nPos + i + 1]; 
      k += 2; 
      nPos += imageWidth; 
     } 
    } 
    return rotateYUV420Degree180(yuv,imageWidth,imageHeight); 
} 
+0

를 u는 명확하게됩니다 .m_in_Array_Encode, i * 4) "내 원시 코드에서 코드 줄을 사용하면 내 원시 코드에 코드를 작성할 수 있으며"TypeConvert :: udwordToBytes (color, encoderContext.m_in_Array_Encode, i * 4) "코드에서 코드 행 –

+0

정적 무효 udwordToBytes (부호 INT 계산해 부호의 char * buf를 긴 인덱스) \t \t \t \t { \t BUF [인덱스 + 3 = 브로 \t \t \t val = val >> 8; \t \t \t BUF [인덱스 + 2] = 브로 & 0xff; \t \t \t 브로 브로 >> = 8; \t \t \t BUF [인덱스 + 1] = 브로 & 0xff; \t \t \t 브로 브로 >> = 8; \t \t \t BUF는 [지수 = 브로는 & 0xff; \t \t}이 바이트로 변환하기위한 코드이며 –

관련 문제