whycxzp
2024-07-27 efa5fe48ebc866ec07a597ef551cf7e13c3b7aba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.whyc.util;
 
import android.media.Image;
 
public class YUVUtil {
 
    public static void YUVToNV21_NV12(Image image, byte[] nv21, int w, int h, String type) {
        Image.Plane[] planes = image.getPlanes();
        int remaining0 = planes[0].getBuffer().remaining();
        int remaining1 = planes[1].getBuffer().remaining();
        int remaining2 = planes[2].getBuffer().remaining();
        //分别准备三个数组接收YUV分量。
        byte[] yRawSrcBytes = new byte[remaining0];
        byte[] uRawSrcBytes = new byte[remaining1];
        byte[] vRawSrcBytes = new byte[remaining2];
        planes[0].getBuffer().get(yRawSrcBytes);
        planes[1].getBuffer().get(uRawSrcBytes);
        planes[2].getBuffer().get(vRawSrcBytes);
        int j = 0, k = 0;
        boolean flag = type.equals("NV21");
        if (type.equals("NV21") || type.equals("NV12")) {
            for (int i = 0; i < nv21.length; i++) {
                if (i < w * h) {
                    //首先填充w*h个Y分量
                    nv21[i] = yRawSrcBytes[i];
                } else {
 
                    if (flag) {
                        //若NV21类型 则Y分量分配完后第一个将是V分量
                        nv21[i] = vRawSrcBytes[j];
                        //PixelStride有用数据步长 = 1紧凑按顺序填充,=2每间隔一个填充数据
                        j += planes[1].getPixelStride();
                    } else {
                        //若NV12类型 则Y分量分配完后第一个将是U分量
                        nv21[i] = uRawSrcBytes[k];
                        //PixelStride有用数据步长 = 1紧凑按顺序填充,=2每间隔一个填充数据
                        k += planes[2].getPixelStride();
                    }
                    //紧接着可以交错UV或者VU排列不停的改变flag标志即可交错排列
                    flag = !flag;
                }
            }
        }else{ //I420标准结构Plannar,YUV分量首先存放w * h 个Y,接着存放 w * h * 0.25 个U最后存放 w * h * 0.25 个V
            for (int i = 0; i < nv21.length; i++) {
                if (i < w * h) {
                    //首先填充w*h个Y分量
                    nv21[i] = yRawSrcBytes[i];
                } else if (i < w * h * 5 / 4) {
                    nv21[i] = uRawSrcBytes[j];
                    j += planes[1].getPixelStride();
                } else {
                    nv21[i] = vRawSrcBytes[k];
                    k += planes[2].getPixelStride();
                }
            }
 
        }
    }
}