const int BYTES_PER_RGB_PIX    = 3; // byts per pixel

        /**
         * Generate a direct RGB {@link ByteBuffer} from a YUV420_888 {@link Image}.
         */
        static ByteBuffer ConvertToRGB(Image yuvImage)
        {
            // TODO: Optimize this with renderscript intrinsic.
            int        width  = yuvImage.Width;
            int        height = yuvImage.Height;
            ByteBuffer buf    = ByteBuffer.AllocateDirect(BYTES_PER_RGB_PIX * width * height);

            Image.Plane yPlane = yuvImage.GetPlanes()[0];
            Image.Plane uPlane = yuvImage.GetPlanes()[1];
            Image.Plane vPlane = yuvImage.GetPlanes()[2];

            ByteBuffer yBuf = yPlane.Buffer;
            ByteBuffer uBuf = uPlane.Buffer;
            ByteBuffer vBuf = vPlane.Buffer;

            yBuf.Rewind();
            uBuf.Rewind();
            vBuf.Rewind();

            int yRowStride = yPlane.RowStride;
            int vRowStride = vPlane.RowStride;
            int uRowStride = uPlane.RowStride;

            int yPixStride = yPlane.PixelStride;
            int vPixStride = vPlane.PixelStride;
            int uPixStride = uPlane.PixelStride;

            byte[] yuvPixel = { 0, 0, 0 };
            byte[] yFullRow = new byte[yPixStride * (width - 1) + 1];
            byte[] uFullRow = new byte[uPixStride * (width / 2 - 1) + 1];
            byte[] vFullRow = new byte[vPixStride * (width / 2 - 1) + 1];
            byte[] finalRow = new byte[BYTES_PER_RGB_PIX * width];
            for (int i = 0; i < height; i++)
            {
                int halfH = i / 2;
                yBuf.Position(yRowStride * i);
                yBuf.Get(yFullRow);
                uBuf.Position(uRowStride * halfH);
                uBuf.Get(uFullRow);
                vBuf.Position(vRowStride * halfH);
                vBuf.Get(vFullRow);
                for (int j = 0; j < width; j++)
                {
                    int halfW = j / 2;
                    yuvPixel[0] = yFullRow[yPixStride * j];
                    yuvPixel[1] = uFullRow[uPixStride * halfW];
                    yuvPixel[2] = vFullRow[vPixStride * halfW];
                    YuvToRgb(yuvPixel, j * BYTES_PER_RGB_PIX, /*out*/ finalRow);
                }
                buf.Put(finalRow);
            }

            yBuf.Rewind();
            uBuf.Rewind();
            vBuf.Rewind();
            buf.Rewind();
            return(buf);
        }
Ejemplo n.º 2
0
        private byte[] YUV_420_888_toRGBIntrinsics(Image image)
        {
            if (image == null)
            {
                return(null);
            }

            long starttime = DateTime.Now.Millisecond;
            int  W         = image.Width;
            int  H         = image.Height;

            Image.Plane Y = image.GetPlanes()[0];
            Image.Plane U = image.GetPlanes()[1];
            Image.Plane V = image.GetPlanes()[2];

            int Yb = Y.Buffer.Remaining();
            int Ub = U.Buffer.Remaining();
            int Vb = V.Buffer.Remaining();

            byte[] data = new byte[Yb + Ub + Vb];


            Y.Buffer.Get(data, 0, Yb);
            V.Buffer.Get(data, Yb, Vb);
            U.Buffer.Get(data, Yb + Vb, Ub);



            //        RenderScript rs = RenderScript.create(context);
            //        ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
            //
            //        Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
            //        Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
            //
            //        Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
            //        Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
            //
            //        in.copyFromUnchecked(data);
            //
            //        yuvToRgbIntrinsic.setInput(in);
            //        yuvToRgbIntrinsic.forEach(out);
            //        int[] argb = new int[data.length];
            //        byte[] argb = new byte[image.Width *image.Height * 4 ];
            //        out.copyTo(argb);

            Log.Error("wtf", "YUV_420_888_toRGBIntrinsics->" + (DateTime.Now.Millisecond - starttime));
            return(data);
        }