已經(jīng)有很多文章介紹Image對象,這里不再多解釋.
寫在這里一是為了做個筆記記錄,二是查了好多資料確實沒有找到Y(jié)UV_420_888轉(zhuǎn)換YUYV的方法,希望幫助更多人吧.
public static byte[] getYUYVFromImage420(Image image) {
try {
//獲取源數(shù)據(jù)绣檬,如果是YUV格式的數(shù)據(jù)planes.length = 3
//plane[i]里面的實際數(shù)據(jù)可能存在byte[].length <= capacity (緩沖區(qū)總大小)
final Image.Plane[] planes = image.getPlanes();
//數(shù)據(jù)有效寬度嗽测,一般的痛单,圖片width <= rowStride乏矾,這也是導(dǎo)致byte[].length <= capacity的原因
//所以我們只取width部分
int width = image.getWidth();
int height = image.getHeight();
//此處用來裝填最終的YUV數(shù)據(jù),需要2倍的圖片大小孔庭,因為Y U V 比例為 4:2:2
byte[] yuvBytes = new byte[width * height * ImageFormat.getBitsPerPixel(ImageFormat.YUV_422_888) / 8];
//臨時存儲y u v數(shù)據(jù)的
byte[] yBytes = new byte[width * height];
//--分離Y數(shù)據(jù)
ByteBuffer buffer = planes[0].getBuffer();
buffer.get(yBytes);
int uPixelsStride, vPixelsStride;
//--分離U數(shù)據(jù)
uPixelsStride = planes[1].getPixelStride();
buffer = planes[1].getBuffer();
byte[] uTempBytes = new byte[buffer.capacity()];
buffer.get(uTempBytes);
vPixelsStride = planes[2].getPixelStride();
//--分離V數(shù)據(jù)
buffer = planes[2].getBuffer();
byte[] vTempBytes = new byte[buffer.capacity()];
buffer.get(vTempBytes);
int ySrcIndex = 0;
int uSrcIndex = 0;
int vSrcIndex = 0;
int yDstIndex = 0;
for (int j = 0; j < height / 2; j++) {
int uvWidth = width;
for (int k = 0; k < uvWidth / 2; k++) {
// Y
yuvBytes[yDstIndex] = yBytes[ySrcIndex];
yuvBytes[yDstIndex + uvWidth * 2] = yBytes[ySrcIndex + uvWidth];
yDstIndex++;
ySrcIndex++;
// U
yuvBytes[yDstIndex] = uTempBytes[uSrcIndex];
yuvBytes[yDstIndex + uvWidth * 2] = uTempBytes[uSrcIndex];
yDstIndex++;
// Y
yuvBytes[yDstIndex] = yBytes[ySrcIndex];
yuvBytes[yDstIndex + uvWidth * 2] = yBytes[ySrcIndex + uvWidth];
yDstIndex++;
ySrcIndex++;
// V
yuvBytes[yDstIndex] = vTempBytes[vSrcIndex];
yuvBytes[yDstIndex + uvWidth * 2] = vTempBytes[vSrcIndex];
yDstIndex++;
uSrcIndex += uPixelsStride;
vSrcIndex += vPixelsStride;
}
yDstIndex += uvWidth * 2;
ySrcIndex += uvWidth;
}
image.close();
return yuvBytes;
} catch (final Exception e) {
if (image != null) {
image.close();
}
Log.e("ArMn", android.util.Log.getStackTraceString(e));
}
return null;
}