#region YUV 转 RGB
private static int R = 0;
private static int G = 1;
private static int B = 2;
public static Bitmap GetImagByYuvToRGB(string path, int width, int height)
{
//int width = 1280;
//int height = 720;
// string path = "D:\\1.yuv";
// Bitmap bmp = Helper.GetImagByYuvToRGB(path, width, height);
// bmp.Save("D:\\yuv2bmp_1.bmp")
int imgSize = width * height;
int frameSize = imgSize + (imgSize >> 1);
Bitmap bm = null;
byte[] yuv = new byte[frameSize];
byte[] rgb = new byte[3 * imgSize];
using (FileStream fs = File.OpenRead(path))
{
int frame = (int)fs.Length / frameSize;
using (BinaryReader br = new BinaryReader(fs))
{
while (br.PeekChar() != -1)
{
// 循环读取每一桢
br.Read(yuv, 0, frameSize);
}
}
bm = Helper.Yuv420_RGB24(yuv, width, height);
// bm.Save("D:\\yuv2bmp_1.bmp");
}
return bm;
}
/// <summary>
/// YUV420转RGB24
/// </summary>
/// <param name="yuvFrame">YUV 格式图像数据。</param>
/// <param name="rgbFrame">RGB 格式图像数据。</param>
/// <param name="width">图像宽(单位:像素)。</param>
/// <param name="height">图像高(单位:像素)。</param>
/// <returns>Bitmap图片</returns>
public static Bitmap Yuv420_RGB24(byte[] yuvFrame, byte[] rgbFrame, int width, int height)
{
double[,] YUV2RGB_CONVERT_MATRIX = new double[3, 3] { { 1, 0, 1.4022 }, { 1, -0.3456, -0.7145 }, { 1, 1.771, 0 } };//yuv420
int uIndex = width * height;
int vIndex = uIndex + ((width * height) >> 2);
int gIndex = width * height;
int bIndex = gIndex * 2;
int temp = 0;
//图片为pic1,RGB颜色的二进制数据转换得的int r,g,b;
Bitmap bm = new Bitmap(width, height);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// R分量
temp = (int)(yuvFrame[y * width + x] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[0, 2]);
rgbFrame[y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
// G分量
temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 1] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 2]);
rgbFrame[gIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
// B分量
temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[2, 1]);
rgbFrame[bIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
Color c = Color.FromArgb(rgbFrame[y * width + x], rgbFrame[gIndex + y * width + x], rgbFrame[bIndex + y * width + x]);
bm.SetPixel(x, y, c);
}
}
return bm;
}
public static Bitmap Yuv420_RGB24(byte[] src, int width, int height)
{
int numOfPixel = width * height;
int bIndex = numOfPixel * 2;
int positionOfV = numOfPixel;
int positionOfU = numOfPixel / 4 + numOfPixel;
int[] rgb = new int[numOfPixel * 3];
Bitmap bm = new Bitmap(width, height);
for (int i = 0; i < height; i++)
{
int startY = i * width;
int step = (i / 2) * (width / 2);
int startU = positionOfV + step;
int startV = positionOfU + step;
for (int j = 0; j < width; j++)
{
int Y = startY + j;
int U = startU + j / 2;
int V = startV + j / 2;
int index = Y * 3;
RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
rgb[index + R] = tmp.r;
rgb[index + G] = tmp.g;
rgb[index + B] = tmp.b;
Color c = Color.FromArgb(rgb[index + R], rgb[index + G], rgb[index + B]);
bm.SetPixel(j, i, c);
}
}
return bm;
}
public static Bitmap Yuv422_RGB24(byte[] src, int width, int height)
{
int numOfPixel = width * height;
int positionOfU = numOfPixel;
int positionOfV = numOfPixel / 2 + numOfPixel;
int[] rgb = new int[numOfPixel * 3];
Bitmap bm = new Bitmap(width, height);
for (int i = 0; i < height; i++)
{
int startY = i * width;
int step = i * width / 2;
int startU = positionOfU + step;
int startV = positionOfV + step;
for (int j = 0; j < width; j++)
{
int Y = startY + j;
int U = startU + j / 2;
int V = startV + j / 2;
int index = Y * 3;
RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
//rgb[index+R] = (int)((src[Y]&0xff) + 1.4075 * ((src[V]&0xff)-128));
//rgb[index+G] = (int)((src[Y]&0xff) - 0.3455 * ((src[U]&0xff)-128) - 0.7169*((src[V]&0xff)-128));
//rgb[index+B] = (int)((src[Y]&0xff) + 1.779 * ((src[U]&0xff)-128))
rgb[index + R] = tmp.r;
rgb[index + G] = tmp.g;
rgb[index + B] = tmp.b;
Color c = Color.FromArgb(rgb[index + R], rgb[index + G], rgb[index + B]);
bm.SetPixel(j, i, c);
}
}
return bm;
}
private static RGB yuvTorgb(byte Y, byte U, byte V)
{
RGB rgb = new RGB();
rgb.r = (int)((Y & 0xff) + 1.4075 * ((V & 0xff) - 128));
rgb.g = (int)((Y & 0xff) - 0.3455 * ((U & 0xff) - 128) - 0.7169 * ((V & 0xff) - 128));
rgb.b = (int)((Y & 0xff) + 1.779 * ((U & 0xff) - 128));
rgb.r = (rgb.r < 0 ? 0 : rgb.r > 255 ? 255 : rgb.r);
rgb.g = (rgb.g < 0 ? 0 : rgb.g > 255 ? 255 : rgb.g);
rgb.b = (rgb.b < 0 ? 0 : rgb.b > 255 ? 255 : rgb.b);
return rgb;
}
#endregion
YUV 转 RGB
于 2025-02-25 13:16:57 首次发布