Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate an YUV byte array on Android

Tags:

I'm looking to rotate a YUV frame preview recieved from a Preview Callblack, so far I've founded this post which cointains an algorithm to rotate the frame preview but is messing the preview image camera pixels rotated

another way to rotate the image will be creating a jpg out of the YUV image, create a bitmap, rotate a bitmap and obtaining the byte array of the bitmap, but I really need the format in YUV (NV21).

FYI. the reason I'm asking this is because I have a camera app that supports rotation, but the frame previews are coming back in landscape mode only.

like image 570
Francisco Avatar asked Jan 05 '13 02:01

Francisco


2 Answers

The following method can rotate a YUV420 byte array by 90 degree.

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

(Note that this might only work if the width and height is a factor of 4)

like image 93
Johannes Avatar answered Sep 21 '22 14:09

Johannes


Here are the options to turn a different corner (90, 180, 270):

public static 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 static 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; }  public static 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); } 
like image 41
Qulery Avatar answered Sep 22 '22 14:09

Qulery