Java tutorial
//package com.java2s; import android.graphics.ImageFormat; import android.util.Log; public class Main { public static byte[] swapColors(byte[] data, int w, int h, int pictureFormat) { switch (pictureFormat) { case ImageFormat.YV12: return swapYUV420Planar(data); case ImageFormat.NV21: return swapYUV420SemiPlanar(data, w, h); default: Log.w("Util", "No color format to swap"); } return data; } /** * Performs in place Cb and Cr swapping for a YUV 4:2:0 Planar frame <br> * The frame could be formatted as : * <ul> * <li>YUV420p, that is [Y1Y2Y3Y4....][U1U2...][V1V2...]</li> or * <li>YV12, that is [Y1Y2Y3Y4....][V1V2...][U1U2...]</li> * </ul> * Whatever will be the input format, the function converts it in the other format * @param frame the YUV420p frame * @return */ public static byte[] swapYUV420Planar(byte[] frame) { int p = frame.length * 2 / 3; //<-- this is equals to width*height int idx = p; int Clen = p / 4; //<-- that is, (width/2*height/2) for (int i = 0; i < Clen; i++) { int uIdx = idx + i; int vIdx = idx + i + Clen; byte U = frame[uIdx]; byte V = frame[vIdx]; byte tmp = U; frame[uIdx] = V; frame[vIdx] = tmp; } return frame; } /** * Performs in place Cb and Cr swapping for a YUV 4:2:0 SemiPlanar frame <br> * The frame could be formatted as : * <ul> * <li>NV12, that is [Y1Y2Y3Y4....][U1V1U2V2...]</li> or * <li>NV21, that is [Y1Y2Y3Y4....][V1U1V2U2...]</li> * </ul> * Whatever will be the input format, the function converts it in the other format * @param frame the YUV420sp frame * @return */ public static byte[] swapYUV420SemiPlanar(byte[] frame, int width, int height) { int p = frame.length * 2 / 3; //<-- this is equals to width*height int idx = p; int Clen = p / 2; //<-- that is, (width*height/2) for (int i = 0; i < Clen; i += 2) { int uIdx = idx + i; int vIdx = idx + i + 1; byte U = frame[uIdx]; byte V = frame[vIdx]; byte tmp = U; frame[uIdx] = V; frame[vIdx] = tmp; } return frame; } }