123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- using Android.Graphics;
- using Com.Flyinsono.Util;
- using Java.Nio;
- using System.Runtime.InteropServices;
- namespace Vinno.vCloud.FIS.CrossPlatform.Android.LiveVideo
- {
- public class YuvHelper
- {
- /// <summary>
- /// 将I420转成ABGR数据
- /// </summary>
- /// <param name="buffer">I420 buffer</param>
- /// <param name="bytes">ABGR bytes</param>
- /// <param name="width">图片宽度</param>
- /// <param name="height">图片高度</param>
- public static void ConvertI420ToABGR(ByteBuffer buffer, byte[] bytes, int width, int height)
- {
- YuvUtil.I420ToABGR(buffer, width, height, bytes);
- }
- /// <summary>
- /// 将ABGR数据转成I420
- /// </summary>
- /// <param name="abgr">ABGR buffer</param>
- /// <param name="width">图像宽度</param>
- /// <param name="height">图像高度</param>
- /// <param name="i420">I420 buffer</param>
- public static void ConvertABGRToI420(byte[] abgr, int width, int height, byte[] i420)
- {
- YuvUtil.ABGRToI420(abgr, width, height, i420);
- }
- /// <summary>
- /// 将ABGR数据转成I420
- /// </summary>
- /// <param name="abgr">ABGR buffer</param>
- /// <param name="width">图像宽度</param>
- /// <param name="height">图像高度</param>
- /// <param name="i420">I420 buffer</param>
- public static void ConvertABGRToI420(ByteBuffer abgr, int width, int height, byte[] i420)
- {
- YuvUtil.ABGRToI4202(abgr, width, height, i420);
- }
- /// <summary>
- /// 将ABGR数据转成I420
- /// </summary>
- /// <param name="abgr">ABGR buffer</param>
- /// <param name="width">图像宽度</param>
- /// <param name="height">图像高度</param>
- /// <param name="i420">I420 buffer</param>
- public static void ConvertABGRToI420(ByteBuffer abgr, int width, int height, ByteBuffer i420)
- {
- YuvUtil.ABGRToI4203(abgr, width, height, i420);
- }
- /// <summary>
- /// 将图片按比例缩放
- /// </summary>
- /// <param name="src_argb">原图</param>
- /// <param name="src_width">原图宽</param>
- /// <param name="src_height">原图高</param>
- /// <param name="dst_argb">目标图</param>
- /// <param name="dst_width">目标图宽</param>
- /// <param name="dst_height">目标图高</param>
- 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);// 最后一位可能是过滤模式
- }
- /// <summary>
- /// 将图片按比例缩放
- /// </summary>
- /// <param name="src_argb">原图</param>
- /// <param name="src_width">原图宽</param>
- /// <param name="src_height">原图高</param>
- /// <param name="dst_argb">目标图</param>
- /// <param name="dst_width">目标图宽</param>
- /// <param name="dst_height">目标图高</param>
- 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);//最后一位可能是过滤模式
- }
- /// <summary>
- /// 将I420转成ABGR数据
- /// </summary>
- /// <param name="bytes">I420 bytes</param>
- /// <param name="buffer">ABGR buffer</param>
- /// <param name="width">图片宽度</param>
- /// <param name="height">图片高度</param>
- public static void ConvertI420ToABGR(byte[] bytes, ByteBuffer buffer, int width, int height)
- {
- YuvUtil.I420ToABGR4(bytes, width, height, buffer);
- }
- /// <summary>
- /// 将I420转成ABGR数据
- /// </summary>
- /// <param name="i420buffer">I420 buffer</param>
- /// <param name="abgrBuffer">ABGR buffer</param>
- /// <param name="width">图片宽度</param>
- /// <param name="height">图片高度</param>
- public static void ConvertI420ToABGR(ByteBuffer i420buffer, ByteBuffer abgrBuffer, int width, int height)
- {
- YuvUtil.I420ToABGR3(i420buffer, width, height, abgrBuffer);
- }
- /// <summary>
- /// 将I420转成ABGR数据
- /// </summary>
- /// <param name="bytes">I420 bytes</param>
- /// <param name="abgr">ABGR bytes</param>
- /// <param name="width">图片宽度</param>
- /// <param name="height">图片高度</param>
- public static void ConvertI420ToABGR(byte[] bytes, byte[] abgr, int width, int height)
- {
- YuvUtil.I420ToABGR2(bytes, width, height, abgr);
- }
- /// <summary>
- /// 将ABGR转换成Nv21
- /// </summary>
- /// <param name="abgr"></param>
- /// <param name="width"></param>
- /// <param name="height"></param>
- /// <param name="nv21"></param>
- public static void ConvertABGRToNv21(ByteBuffer abgr, int width, int height, ByteBuffer nv21)
- {
- YuvUtil.ABGRToNv21(abgr, width, height, nv21);
- }
- /// <summary>
- /// 将ABGR转成Bitmap
- /// </summary>
- /// <param name="bytes"></param>
- /// <param name="bitmap"></param>
- /// <param name="len"></param>
- 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();
- }
- /// <summary>
- /// 将Nv21转成I420
- /// </summary>
- /// <param name="src">源数据</param>
- /// <param name="width">宽度</param>
- /// <param name="height">高度</param>
- /// <param name="dst">目的数据</param>
- public static void Nv21ToI420(byte[] src, int width, int height, byte[] dst)
- {
- YuvUtil.Nv21ToI420(src, width, height, dst);
- }
- /// <summary>
- /// NV21旋转
- /// </summary>
- /// <param name="src">源数据</param>
- /// <param name="width">宽度</param>
- /// <param name="height">高度</param>
- /// <param name="dst">目的数据</param>
- /// <param name="degree">角度</param>
- 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++;
- }
- }
- }
- }
- }
- }
|