YuvHelper.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using Android.Graphics;
  2. using Com.Flyinsono.Util;
  3. using Java.Nio;
  4. using System.Runtime.InteropServices;
  5. namespace Vinno.vCloud.FIS.CrossPlatform.Android.LiveVideo
  6. {
  7. public class YuvHelper
  8. {
  9. /// <summary>
  10. /// 将I420转成ABGR数据
  11. /// </summary>
  12. /// <param name="buffer">I420 buffer</param>
  13. /// <param name="bytes">ABGR bytes</param>
  14. /// <param name="width">图片宽度</param>
  15. /// <param name="height">图片高度</param>
  16. public static void ConvertI420ToABGR(ByteBuffer buffer, byte[] bytes, int width, int height)
  17. {
  18. YuvUtil.I420ToABGR(buffer, width, height, bytes);
  19. }
  20. /// <summary>
  21. /// 将ABGR数据转成I420
  22. /// </summary>
  23. /// <param name="abgr">ABGR buffer</param>
  24. /// <param name="width">图像宽度</param>
  25. /// <param name="height">图像高度</param>
  26. /// <param name="i420">I420 buffer</param>
  27. public static void ConvertABGRToI420(byte[] abgr, int width, int height, byte[] i420)
  28. {
  29. YuvUtil.ABGRToI420(abgr, width, height, i420);
  30. }
  31. /// <summary>
  32. /// 将ABGR数据转成I420
  33. /// </summary>
  34. /// <param name="abgr">ABGR buffer</param>
  35. /// <param name="width">图像宽度</param>
  36. /// <param name="height">图像高度</param>
  37. /// <param name="i420">I420 buffer</param>
  38. public static void ConvertABGRToI420(ByteBuffer abgr, int width, int height, byte[] i420)
  39. {
  40. YuvUtil.ABGRToI4202(abgr, width, height, i420);
  41. }
  42. /// <summary>
  43. /// 将ABGR数据转成I420
  44. /// </summary>
  45. /// <param name="abgr">ABGR buffer</param>
  46. /// <param name="width">图像宽度</param>
  47. /// <param name="height">图像高度</param>
  48. /// <param name="i420">I420 buffer</param>
  49. public static void ConvertABGRToI420(ByteBuffer abgr, int width, int height, ByteBuffer i420)
  50. {
  51. YuvUtil.ABGRToI4203(abgr, width, height, i420);
  52. }
  53. /// <summary>
  54. /// 将图片按比例缩放
  55. /// </summary>
  56. /// <param name="src_argb">原图</param>
  57. /// <param name="src_width">原图宽</param>
  58. /// <param name="src_height">原图高</param>
  59. /// <param name="dst_argb">目标图</param>
  60. /// <param name="dst_width">目标图宽</param>
  61. /// <param name="dst_height">目标图高</param>
  62. public static void ScaleARGB(ByteBuffer src_argb, int src_width, int src_height, ByteBuffer dst_argb, int dst_width, int dst_height)
  63. {
  64. YuvUtil.ScaleARGB(src_argb, src_width, src_height, dst_argb, dst_width, dst_height, 3);// 最后一位可能是过滤模式
  65. }
  66. /// <summary>
  67. /// 将图片按比例缩放
  68. /// </summary>
  69. /// <param name="src_argb">原图</param>
  70. /// <param name="src_width">原图宽</param>
  71. /// <param name="src_height">原图高</param>
  72. /// <param name="dst_argb">目标图</param>
  73. /// <param name="dst_width">目标图宽</param>
  74. /// <param name="dst_height">目标图高</param>
  75. public static void ScaleARGB(ByteBuffer src_argb, int src_width, int src_height, byte[] dst_argb, int dst_width, int dst_height)
  76. {
  77. YuvUtil.ScaleARGB2(src_argb, src_width, src_height, dst_argb, dst_width, dst_height, 3);//最后一位可能是过滤模式
  78. }
  79. /// <summary>
  80. /// 将I420转成ABGR数据
  81. /// </summary>
  82. /// <param name="bytes">I420 bytes</param>
  83. /// <param name="buffer">ABGR buffer</param>
  84. /// <param name="width">图片宽度</param>
  85. /// <param name="height">图片高度</param>
  86. public static void ConvertI420ToABGR(byte[] bytes, ByteBuffer buffer, int width, int height)
  87. {
  88. YuvUtil.I420ToABGR4(bytes, width, height, buffer);
  89. }
  90. /// <summary>
  91. /// 将I420转成ABGR数据
  92. /// </summary>
  93. /// <param name="i420buffer">I420 buffer</param>
  94. /// <param name="abgrBuffer">ABGR buffer</param>
  95. /// <param name="width">图片宽度</param>
  96. /// <param name="height">图片高度</param>
  97. public static void ConvertI420ToABGR(ByteBuffer i420buffer, ByteBuffer abgrBuffer, int width, int height)
  98. {
  99. YuvUtil.I420ToABGR3(i420buffer, width, height, abgrBuffer);
  100. }
  101. /// <summary>
  102. /// 将I420转成ABGR数据
  103. /// </summary>
  104. /// <param name="bytes">I420 bytes</param>
  105. /// <param name="abgr">ABGR bytes</param>
  106. /// <param name="width">图片宽度</param>
  107. /// <param name="height">图片高度</param>
  108. public static void ConvertI420ToABGR(byte[] bytes, byte[] abgr, int width, int height)
  109. {
  110. YuvUtil.I420ToABGR2(bytes, width, height, abgr);
  111. }
  112. /// <summary>
  113. /// 将ABGR转换成Nv21
  114. /// </summary>
  115. /// <param name="abgr"></param>
  116. /// <param name="width"></param>
  117. /// <param name="height"></param>
  118. /// <param name="nv21"></param>
  119. public static void ConvertABGRToNv21(ByteBuffer abgr, int width, int height, ByteBuffer nv21)
  120. {
  121. YuvUtil.ABGRToNv21(abgr, width, height, nv21);
  122. }
  123. /// <summary>
  124. /// 将ABGR转成Bitmap
  125. /// </summary>
  126. /// <param name="bytes"></param>
  127. /// <param name="bitmap"></param>
  128. /// <param name="len"></param>
  129. public static void ConvertABGRToBitmap(byte[] bytes, Bitmap bitmap, int len)
  130. {
  131. if (bitmap == null || bitmap.IsRecycled) return;
  132. Marshal.Copy(bytes, 0, bitmap.LockPixels(), len);
  133. bitmap.UnlockPixels();
  134. }
  135. /// <summary>
  136. /// 将Nv21转成I420
  137. /// </summary>
  138. /// <param name="src">源数据</param>
  139. /// <param name="width">宽度</param>
  140. /// <param name="height">高度</param>
  141. /// <param name="dst">目的数据</param>
  142. public static void Nv21ToI420(byte[] src, int width, int height, byte[] dst)
  143. {
  144. YuvUtil.Nv21ToI420(src, width, height, dst);
  145. }
  146. /// <summary>
  147. /// NV21旋转
  148. /// </summary>
  149. /// <param name="src">源数据</param>
  150. /// <param name="width">宽度</param>
  151. /// <param name="height">高度</param>
  152. /// <param name="dst">目的数据</param>
  153. /// <param name="degree">角度</param>
  154. public static void RotateNV21(byte[] src, int width, int height, byte[] dst, int degree)
  155. {
  156. //YuvUtil.RotateI420(src, width, height, dst, degree);//虽能翻转,但未镜面
  157. if (degree == 90)
  158. {
  159. int wh = width * height;
  160. //旋转Y
  161. int k = 0;
  162. for (int i = 0; i < width; i++)
  163. {
  164. for (int j = height - 1; j >= 0; j--)
  165. {
  166. dst[k] = src[width * j + i];
  167. k++;
  168. }
  169. }
  170. int halfWidth = width >> 1;
  171. int halfHeight = height >> 1;
  172. for (int colIndex = 0; colIndex < halfWidth; colIndex++)
  173. {
  174. for (int rowIndex = halfHeight - 1; rowIndex >= 0; rowIndex--)
  175. {
  176. int index = (halfWidth * rowIndex + colIndex) << 1;
  177. dst[k] = src[wh + index];
  178. k++;
  179. dst[k] = src[wh + index + 1];
  180. k++;
  181. }
  182. }
  183. }
  184. else if (degree == 270)
  185. {
  186. // Rotate and mirror the Y luma
  187. int i = 0;
  188. int maxY;
  189. for (int x = width - 1; x >= 0; x--)
  190. {
  191. maxY = width * (height - 1) + (x << 1);
  192. for (int y = 0; y < height; y++)
  193. {
  194. dst[i] = src[maxY - (y * width + x)];
  195. i++;
  196. }
  197. }
  198. // Rotate and mirror the U and V color components
  199. int uvSize = width * height;
  200. int halfHeight = height >> 1;
  201. i = uvSize;
  202. int maxUV;
  203. for (int x = width - 1; x > 0; x = x - 2)
  204. {
  205. maxUV = width * (halfHeight - 1) + (x << 1) + uvSize;
  206. for (int y = 0; y < halfHeight; y++)
  207. {
  208. dst[i] = src[maxUV - 2 - (y * width + x - 1)];
  209. i++;
  210. dst[i] = src[maxUV - (y * width + x)];
  211. i++;
  212. }
  213. }
  214. }
  215. }
  216. }
  217. }