YUV转BMP

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);
// 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);
                    int start = Environment.TickCount;
                    // 转换为 RGB
                    bm = Helper.ConvertYUV2RGB(yuv, rgb, width, height);
                }
            }
        }
        return bm;
    }
    /// <summary>
    /// 将一桢 YUV 格式的图像转换为一桢 RGB 格式图像并转换成BMP图片。
    /// </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 ConvertYUV2RGB(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 } };
        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 class YuvToRGB {
02. private static int R = 0;
03. private static int G = 1;
04. private static int B = 2;
05. //I420是yuv420格式,是3个plane,排列方式为(Y)(U)(V)
06. public static int[] I420ToRGB(byte[] src, int width, int height){
07. int numOfPixel = width * height;
08. int positionOfV = numOfPixel;
09. int positionOfU = numOfPixel/4 + numOfPixel;
10. int[] rgb = new int[numOfPixel3];
11. for(int i=0; i<height; i++){
12. int startY = i
width;
13. int step = (i/2)(width/2);
14. int startU = positionOfV + step;
15. int startV = positionOfU + step;
16. for(int j = 0; j < width; j++){
17. int Y = startY + j;
18. int U = startU + j/2;
19. int V = startV + j/2;
20. int index = Y
3;
21. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
22. rgb[index+R] = tmp.r;
23. rgb[index+G] = tmp.g;
24. rgb[index+B] = tmp.b;
25. }
26. }
27.
28. return rgb;
29. }
30.
31. private static class RGB{
32. public int r, g, b;
33. }
34.
35. private static RGB yuvTorgb(byte Y, byte U, byte V){
36. RGB rgb = new RGB();
37. rgb.r = (int)((Y&0xff) + 1.4075 * ((V&0xff)-128));
38. rgb.g = (int)((Y&0xff) - 0.3455 * ((U&0xff)-128) - 0.7169*((V&0xff)-128));
39. rgb.b = (int)((Y&0xff) + 1.779 * ((U&0xff)-128));
40. rgb.r =(rgb.r<0? 0: rgb.r>255? 255 : rgb.r);
41. rgb.g =(rgb.g<0? 0: rgb.g>255? 255 : rgb.g);
42. rgb.b =(rgb.b<0? 0: rgb.b>255? 255 : rgb.b);
43. return rgb;
44. }
45.
46. //YV16是yuv422格式,是三个plane,(Y)(U)(V)
47. public static int[] YV16ToRGB(byte[] src, int width, int height){
48. int numOfPixel = width * height;
49. int positionOfU = numOfPixel;
50. int positionOfV = numOfPixel/2 + numOfPixel;
51. int[] rgb = new int[numOfPixel3];
52. for(int i=0; i<height; i++){
53. int startY = i
width;
54. int step = iwidth/2;
55. int startU = positionOfU + step;
56. int startV = positionOfV + step;
57. for(int j = 0; j < width; j++){
58. int Y = startY + j;
59. int U = startU + j/2;
60. int V = startV + j/2;
61. int index = Y
3;
62. //rgb[index+R] = (int)((src[Y]&0xff) + 1.4075 * ((src[V]&0xff)-128));
63. //rgb[index+G] = (int)((src[Y]&0xff) - 0.3455 * ((src[U]&0xff)-128) - 0.7169*((src[V]&0xff)-128));
64. //rgb[index+B] = (int)((src[Y]&0xff) + 1.779 * ((src[U]&0xff)-128));
65. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
66. rgb[index+R] = tmp.r;
67. rgb[index+G] = tmp.g;
68. rgb[index+B] = tmp.b;
69. }
70. }
71. return rgb;
72. }
73.
74. //YV12是yuv420格式,是3个plane,排列方式为(Y)(V)(U)
75. public static int[] YV12ToRGB(byte[] src, int width, int height){
76. int numOfPixel = width * height;
77. int positionOfV = numOfPixel;
78. int positionOfU = numOfPixel/4 + numOfPixel;
79. int[] rgb = new int[numOfPixel3];
80.
81. for(int i=0; i<height; i++){
82. int startY = i
width;
83. int step = (i/2)(width/2);
84. int startV = positionOfV + step;
85. int startU = positionOfU + step;
86. for(int j = 0; j < width; j++){
87. int Y = startY + j;
88. int V = startV + j/2;
89. int U = startU + j/2;
90. int index = Y
3;
91.
92. //rgb[index+R] = (int)((src[Y]&0xff) + 1.4075 * ((src[V]&0xff)-128));
93. //rgb[index+G] = (int)((src[Y]&0xff) - 0.3455 * ((src[U]&0xff)-128) - 0.7169*((src[V]&0xff)-128));
94. //rgb[index+B] = (int)((src[Y]&0xff) + 1.779 * ((src[U]&0xff)-128));
95. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
96. rgb[index+R] = tmp.r;
97. rgb[index+G] = tmp.g;
98. rgb[index+B] = tmp.b;
99. }
100. }
101. return rgb;
102. }
103.
104. //YUY2是YUV422格式,排列是(YUYV),是1 plane
105. public static int[] YUY2ToRGB(byte[] src, int width, int height){
106. int numOfPixel = width * height;
107. int[] rgb = new int[numOfPixel3];
108. int lineWidth = 2
width;
109. for(int i=0; i<height; i++){
110. int startY = ilineWidth;
111. for(int j = 0; j < lineWidth; j+=4){
112. int Y1 = j + startY;
113. int Y2 = Y1+2;
114. int U = Y1+1;
115. int V = Y1+3;
116. int index = (Y1>>1)3;
117. RGB tmp = yuvTorgb(src[Y1], src[U], src[V]);
118. rgb[index+R] = tmp.r;
119. rgb[index+G] = tmp.g;
120. rgb[index+B] = tmp.b;
121. index += 3;
122. tmp = yuvTorgb(src[Y2], src[U], src[V]);
123. rgb[index+R] = tmp.r;
124. rgb[index+G] = tmp.g;
125. rgb[index+B] = tmp.b;
126. }
127. }
128. return rgb;
129. }
130.
131. //UYVY是YUV422格式,排列是(UYVY),是1 plane
132. public static int[] UYVYToRGB(byte[] src, int width, int height){
133. int numOfPixel = width * height;
134. int[] rgb = new int[numOfPixel
3];
135. int lineWidth = 2
width;
136. for(int i=0; i<height; i++){
137. int startU = ilineWidth;
138. for(int j = 0; j < lineWidth; j+=4){
139. int U = j + startU;
140. int Y1 = U+1;
141. int Y2 = U+3;
142. int V = U+2;
143. int index = (U>>1)3;
144. RGB tmp = yuvTorgb(src[Y1], src[U], src[V]);
145. rgb[index+R] = tmp.r;
146. rgb[index+G] = tmp.g;
147. rgb[index+B] = tmp.b;
148. index += 3;
149. tmp = yuvTorgb(src[Y2], src[U], src[V]);
150. rgb[index+R] = tmp.r;
151. rgb[index+G] = tmp.g;
152. rgb[index+B] = tmp.b;
153. }
154. }
155. return rgb;
156. }
157.
158. //NV21是YUV420格式,排列是(Y), (VU),是2 plane
159. public static int[] NV21ToRGB(byte[] src, int width, int height){
160. int numOfPixel = width * height;
161. int positionOfV = numOfPixel;
162. int[] rgb = new int[numOfPixel
3];
163.
164. for(int i=0; i<height; i++){
165. int startY = i
width;
166. int step = i/2width;
167. int startV = positionOfV + step;
168. for(int j = 0; j < width; j++){
169. int Y = startY + j;
170. int V = startV + j/2;
171. int U = V + 1;
172. int index = Y
3;
173. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
174. rgb[index+R] = tmp.r;
175. rgb[index+G] = tmp.g;
176. rgb[index+B] = tmp.b;
177. }
178. }
179. return rgb;
180. }
181.
182. //NV12是YUV420格式,排列是(Y), (UV),是2 plane
183. public static int[] NV12ToRGB(byte[] src, int width, int height){
184. int numOfPixel = width * height;
185. int positionOfU = numOfPixel;
186. int[] rgb = new int[numOfPixel3];
187.
188. for(int i=0; i<height; i++){
189. int startY = i
width;
190. int step = i/2width;
191. int startU = positionOfU + step;
192. for(int j = 0; j < width; j++){
193. int Y = startY + j;
194. int U = startU + j/2;
195. int V = U + 1;
196. int index = Y
3;
197. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
198. rgb[index+R] = tmp.r;
199. rgb[index+G] = tmp.g;
200. rgb[index+B] = tmp.b;
201. }
202. }
203. return rgb;
204. }
205.
206. //NV16是YUV422格式,排列是(Y), (UV),是2 plane
207. public static int[] NV16ToRGB(byte[] src, int width, int height){
208. int numOfPixel = width * height;
209. int positionOfU = numOfPixel;
210. int[] rgb = new int[numOfPixel3];
211.
212. for(int i=0; i<height; i++){
213. int startY = i
width;
214. int step = iwidth;
215. int startU = positionOfU + step;
216. for(int j = 0; j < width; j++){
217. int Y = startY + j;
218. int U = startU + j/2;
219. int V = U + 1;
220. int index = Y
3;
221. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
222. rgb[index+R] = tmp.r;
223. rgb[index+G] = tmp.g;
224. rgb[index+B] = tmp.b;
225. }
226. }
227. return rgb;
228. }
229.
230. //NV61是YUV422格式,排列是(Y), (VU),是2 plane
231. public static int[] NV61ToRGB(byte[] src, int width, int height){
232. int numOfPixel = width * height;
233. int positionOfV = numOfPixel;
234. int[] rgb = new int[numOfPixel3];
235.
236. for(int i=0; i<height; i++){
237. int startY = i
width;
238. int step = iwidth;
239. int startV = positionOfV + step;
240. for(int j = 0; j < width; j++){
241. int Y = startY + j;
242. int V = startV + j/2;
243. int U = V + 1;
244. int index = Y
3;
245. RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
246. rgb[index+R] = tmp.r;
247. rgb[index+G] = tmp.g;
248. rgb[index+B] = tmp.b;
249. }
250. }
251. return rgb;
252. }
253.
254. //YVYU是YUV422格式,排列是(YVYU),是1 plane
255. public static int[] YVYUToRGB(byte[] src, int width, int height){
256. int numOfPixel = width * height;
257. int[] rgb = new int[numOfPixel3];
258. int lineWidth = 2
width;
259. for(int i=0; i<height; i++){
260. int startY = ilineWidth;
261. for(int j = 0; j < lineWidth; j+=4){
262. int Y1 = j + startY;
263. int Y2 = Y1+2;
264. int V = Y1+1;
265. int U = Y1+3;
266. int index = (Y1>>1)3;
267. RGB tmp = yuvTorgb(src[Y1], src[U], src[V]);
268. rgb[index+R] = tmp.r;
269. rgb[index+G] = tmp.g;
270. rgb[index+B] = tmp.b;
271. index += 3;
272. tmp = yuvTorgb(src[Y2], src[U], src[V]);
273. rgb[index+R] = tmp.r;
274. rgb[index+G] = tmp.g;
275. rgb[index+B] = tmp.b;
276. }
277. }
278. return rgb;
279. }
280.
281. //VYUY是YUV422格式,排列是(VYUY),是1 plane
282. public static int[] VYUYToRGB(byte[] src, int width, int height){
283. int numOfPixel = width * height;
284. int[] rgb = new int[numOfPixel
3];
285. int lineWidth = 2
width;
286. for(int i=0; i<height; i++){
287. int startV = i*lineWidth;
288. for(int j = 0; j < lineWidth; j+=4){
289. int V = j + startV;
290. int Y1 = V+1;
291. int Y2 = V+3;
292. int U = V+2;
293. int index = (U>>1)*3;
294. RGB tmp = yuvTorgb(src[Y1], src[U], src[V]);
295. rgb[index+R] = tmp.r;
296. rgb[index+G] = tmp.g;
297. rgb[index+B] = tmp.b;
298. index += 3;
299. tmp = yuvTorgb(src[Y2], src[U], src[V]);
300. rgb[index+R] = tmp.r;
301. rgb[index+G] = tmp.g;
302. rgb[index+B] = tmp.b;
303. }
304. }
305. return rgb;
306. }
307.}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值