using Android.Graphics; using Com.Flyinsono.Util; using Java.Nio; using System.Runtime.InteropServices; namespace Vinno.vCloud.FIS.CrossPlatform.Android.LiveVideo { public class YuvHelper { /// /// 将I420转成ABGR数据 /// /// I420 buffer /// ABGR bytes /// 图片宽度 /// 图片高度 public static void ConvertI420ToABGR(ByteBuffer buffer, byte[] bytes, int width, int height) { YuvUtil.I420ToABGR(buffer, width, height, bytes); } /// /// 将ABGR数据转成I420 /// /// ABGR buffer /// 图像宽度 /// 图像高度 /// I420 buffer public static void ConvertABGRToI420(byte[] abgr, int width, int height, byte[] i420) { YuvUtil.ABGRToI420(abgr, width, height, i420); } /// /// 将ABGR数据转成I420 /// /// ABGR buffer /// 图像宽度 /// 图像高度 /// I420 buffer public static void ConvertABGRToI420(ByteBuffer abgr, int width, int height, byte[] i420) { YuvUtil.ABGRToI4202(abgr, width, height, i420); } /// /// 将ABGR数据转成I420 /// /// ABGR buffer /// 图像宽度 /// 图像高度 /// I420 buffer public static void ConvertABGRToI420(ByteBuffer abgr, int width, int height, ByteBuffer i420) { YuvUtil.ABGRToI4203(abgr, width, height, i420); } /// /// 将图片按比例缩放 /// /// 原图 /// 原图宽 /// 原图高 /// 目标图 /// 目标图宽 /// 目标图高 public static void ScaleARGB(ByteBuffer src_argb, int src_width, int src_height, ByteBuffer dst_argb, int dst_width, int dst_height) { YuvUtil.ScaleARGB(src_argb, src_width, src_height, dst_argb, dst_width, dst_height, 3);// 最后一位可能是过滤模式 } /// /// 将图片按比例缩放 /// /// 原图 /// 原图宽 /// 原图高 /// 目标图 /// 目标图宽 /// 目标图高 public static void ScaleARGB(ByteBuffer src_argb, int src_width, int src_height, byte[] dst_argb, int dst_width, int dst_height) { YuvUtil.ScaleARGB2(src_argb, src_width, src_height, dst_argb, dst_width, dst_height, 3);//最后一位可能是过滤模式 } /// /// 将I420转成ABGR数据 /// /// I420 bytes /// ABGR buffer /// 图片宽度 /// 图片高度 public static void ConvertI420ToABGR(byte[] bytes, ByteBuffer buffer, int width, int height) { YuvUtil.I420ToABGR4(bytes, width, height, buffer); } /// /// 将I420转成ABGR数据 /// /// I420 buffer /// ABGR buffer /// 图片宽度 /// 图片高度 public static void ConvertI420ToABGR(ByteBuffer i420buffer, ByteBuffer abgrBuffer, int width, int height) { YuvUtil.I420ToABGR3(i420buffer, width, height, abgrBuffer); } /// /// 将I420转成ABGR数据 /// /// I420 bytes /// ABGR bytes /// 图片宽度 /// 图片高度 public static void ConvertI420ToABGR(byte[] bytes, byte[] abgr, int width, int height) { YuvUtil.I420ToABGR2(bytes, width, height, abgr); } /// /// 将ABGR转换成Nv21 /// /// /// /// /// public static void ConvertABGRToNv21(ByteBuffer abgr, int width, int height, ByteBuffer nv21) { YuvUtil.ABGRToNv21(abgr, width, height, nv21); } /// /// 将ABGR转成Bitmap /// /// /// /// public static void ConvertABGRToBitmap(byte[] bytes, Bitmap bitmap, int len) { if (bitmap == null || bitmap.IsRecycled) return; Marshal.Copy(bytes, 0, bitmap.LockPixels(), len); bitmap.UnlockPixels(); } /// /// 将Nv21转成I420 /// /// 源数据 /// 宽度 /// 高度 /// 目的数据 public static void Nv21ToI420(byte[] src, int width, int height, byte[] dst) { YuvUtil.Nv21ToI420(src, width, height, dst); } /// /// NV21旋转 /// /// 源数据 /// 宽度 /// 高度 /// 目的数据 /// 角度 public static void RotateNV21(byte[] src, int width, int height, byte[] dst, int degree) { //YuvUtil.RotateI420(src, width, height, dst, degree);//虽能翻转,但未镜面 if (degree == 90) { int wh = width * height; //旋转Y int k = 0; for (int i = 0; i < width; i++) { for (int j = height - 1; j >= 0; j--) { dst[k] = src[width * j + i]; k++; } } int halfWidth = width >> 1; int halfHeight = height >> 1; for (int colIndex = 0; colIndex < halfWidth; colIndex++) { for (int rowIndex = halfHeight - 1; rowIndex >= 0; rowIndex--) { int index = (halfWidth * rowIndex + colIndex) << 1; dst[k] = src[wh + index]; k++; dst[k] = src[wh + index + 1]; k++; } } } else if (degree == 270) { // Rotate and mirror the Y luma int i = 0; int maxY; for (int x = width - 1; x >= 0; x--) { maxY = width * (height - 1) + (x << 1); for (int y = 0; y < height; y++) { dst[i] = src[maxY - (y * width + x)]; i++; } } // Rotate and mirror the U and V color components int uvSize = width * height; int halfHeight = height >> 1; i = uvSize; int maxUV; for (int x = width - 1; x > 0; x = x - 2) { maxUV = width * (halfHeight - 1) + (x << 1) + uvSize; for (int y = 0; y < halfHeight; y++) { dst[i] = src[maxUV - 2 - (y * width + x - 1)]; i++; dst[i] = src[maxUV - (y * width + x)]; i++; } } } } } }