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++;
}
}
}
}
}
}