Yuv12 轉 RGB24

http://www.cnblogs.com/pqmagic/archive/2008/05/29/1209756.html

發布一個YV12轉RGB24的類(.NET CF)

    最近一直在做Windows Mobile的開發,需要用到從攝像頭讀取圖像,並能夠處理每一幀。
    但遇到這樣一個問題,從攝像頭讀取的圖像原始格式為YV12,要實現預覽必須轉化為RGB24。Dshow中有一些filter應該也能完成,但自己對Dshow了解不多,偷偷懶,找找其他辦法:-)
    在 http://seac.blogchina.com/seac/583337.html上找到一篇關於YV12轉RGB24的文章,采用的是完全查表法,把它封裝到Native DLL中,每獲取到一幀後,P/invoke這個方法進行轉化。但有這樣幾個問題:1,頻繁的P/Invoke是項耗時的操作;2,圖像反轉;3,經轉化後的圖像有鋸齒狀(行列錯位)
    試著用c#來完成轉換,經調試,在dopod 595機子上沒問題,速度比P/Invoke要快!
   
 1 public  class YV12ToRGB
 2      {
 3        private int width;
 4        private int height;
 5        private int length;
 6        private int v;  //v值的起始位置
 7        private int u;  //u值的起始位置
 8        private int rdif, invgdif, bdif;
 9        private int[] Table_fv1;
10        private int[] Table_fv2;
11        private int[] Table_fu1;
12        private int[] Table_fu2;
13        private int[] rgb = new int[3];
14        private int m, n, i, j, hfWidth;
15        private bool addHalf = true;
16        private int py;
17        private int pos, pos1;//dopod 595 圖像調整
18        private byte temp;
19
20        public YV12ToRGB(int iWidth, int iHeight)
21        {
22            Table_fv1 = new int[256{ -180, -179, -177, -176, -174, -173, -172, -170, -169, -167, -166, -165, -163, -162, -160, -159, -158, -156, -155, -153, -152, -151, -149, -148, -146, -145, -144, -142, -141, -139, -138, -137, -135, -134, -132, -131, -130, -128, -127, -125, -124, -123, -121, -120, -118, -117, -115, -114, -113, -111, -110, -108, -107, -106, -104, -103, -101, -100, -99, -97, -96, -94, -93, -92, -90, -89, -87, -86, -85, -83, -82, -80, -79, -78, -76, -75, -73, -72, -71, -69, -68, -66, -65, -64, -62, -61, -59, -58, -57, -55, -54, -52, -51, -50, -48, -47, -45, -44, -43, -41, -40, -38, -37, -36, -34, -33, -31, -30, -29, -27, -26, -24, -23, -22, -20, -19, -17, -16, -15, -13, -12, -10, -9, -8, -6, -5, -3, -20124578911121415161819212223252628293032333536373940424344464749505153545657586061636465676870717274757778798182848586888991929395969899100102103105106107109110112113114116117119120122123124126127129130131133134136137138140141143144145147148150151152154155157158159161162164165166168169171172173175176178 };
23            Table_fv2 = new int[256{ -92, -91, -91, -90, -89, -88, -88, -87, -86, -86, -85, -84, -83, -83, -82, -81, -81, -80, -79, -78, -78, -77, -76, -76, -75, -74, -73, -73, -72, -71, -71, -70, -69, -68, -68, -67, -66, -66, -65, -64, -63, -63, -62, -61, -61, -60, -59, -58, -58, -57, -56, -56, -55, -54, -53, -53, -52, -51, -51, -50, -49, -48, -48, -47, -46, -46, -45, -44, -43, -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35, -34, -33, -33, -32, -31, -31, -30, -29, -28, -28, -27, -26, -26, -25, -24, -23, -23, -22, -21, -21, -20, -19, -18, -18, -17, -16, -16, -15, -14, -13, -13, -12, -11, -11, -10, -9, -8, -8, -7, -6, -6, -5, -4, -3, -3, -2, -100122345567789101011121213141515161717181920202122222324252526272728293030313232333435353637373839404041424243444545464747484950505152525354555556575758596060616262636465656667676869707071727273747575767777787980808182828384858586878788899090 };
24            Table_fu1 = new int[256{ -44, -44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -41, -40, -40, -40, -39, -39, -39, -38, -38, -38, -37, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -33, -33, -33, -32, -32, -32, -31, -31, -31, -30, -30, -30, -29, -29, -29, -28, -28, -28, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -24, -23, -23, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -11, -11, -11, -10, -10, -10, -9, -9, -9, -8, -8, -8, -7, -7, -7, -6, -6, -6, -5, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -10001112223334445556667778889991010111111121212131313141414151515161616171717181818191919202020212122222223232324242425252526262627272728282829292930303031313132323333333434343535353636363737373838383939394040404141414242424343 };
25            Table_fu2 = new int[256{ -227, -226, -224, -222, -220, -219, -217, -215, -213, -212, -210, -208, -206, -204, -203, -201, -199, -197, -196, -194, -192, -190, -188, -187, -185, -183, -181, -180, -178, -176, -174, -173, -171, -169, -167, -165, -164, -162, -160, -158, -157, -155, -153, -151, -149, -148, -146, -144, -142, -141, -139, -137, -135, -134, -132, -130, -128, -126, -125, -123, -121, -119, -118, -116, -114, -112, -110, -109, -107, -105, -103, -102, -100, -98, -96, -94, -93, -91, -89, -87, -86, -84, -82, -80, -79, -77, -75, -73, -71, -70, -68, -66, -64, -63, -61, -59, -57, -55, -54, -52, -50, -48, -47, -45, -43, -41, -40, -38, -36, -34, -32, -31, -29, -27, -25, -24, -22, -20, -18, -16, -15, -13, -11, -9, -8, -6, -4, -2013578101214151719212324262830313335373940424446474951535456586062636567697072747678798183858688909293959799101102104106108109111113115117118120122124125127129131133134136138140141143145147148150152154156157159161163164166168170172173175177179180182184186187189191193195196198200202203205207209211212214216218219221223225 };
26            width = iWidth;
27            height = iHeight;
28            length = iWidth * iHeight;
29            v = length;
30            u = (length * 5) >> 2;
31            hfWidth = iWidth >> 1;
32        }

33
34        public bool Convert(byte[] yv12, ref  byte[] rgb24)
35        {
36            if (yv12.Length == 0 || rgb24.Length == 0)
37                return false;
38            m = -width;
39            n = -hfWidth;
40            for (int y = 0; y < height; y++)
41            {
42                m += width;
43                if (addHalf)
44                {
45                    n += hfWidth;
46                    addHalf = false;
47                }

48                else
49                {
50                    addHalf = true;
51                }

52                for (int x = 0; x < width; x++)
53                {
54                    i = m + x;
55                    j = n + (x >> 1);
56                    py = (int)yv12[i];
57                    rdif = Table_fv1[(int)yv12[v + j]];
58                    invgdif = Table_fu1[(int)yv12[u + j]] + Table_fv2[(int)yv12[v + j]];
59                    bdif = Table_fu2[(int)yv12[u + j]];
60
61                    rgb[2] = py + rdif;
62                    rgb[1] = py - invgdif;
63                    rgb[0] = py + bdif;
64
65                    j = m + x;
66                    i = (j << 1) + j;
67
68                    for (j = 0; j < 3; j++)
69                    {
70                        rgb24[i + j] = (byte)((rgb[j] < 0) ? 0 : ((rgb[j] > 255) ? 255 : rgb[j]));
71                    }

72                    if (x % 4 == 3)
73                    {
74                        pos = (m + x - 1) * 3;
75                        pos1 = (m + x) * 3;
76                        temp = rgb24[pos];
77                        rgb24[pos] = rgb24[pos1];
78                        rgb24[pos1] = temp;
79
80                        temp = rgb24[pos + 1];
81                        rgb24[pos + 1] = rgb24[pos1 + 1];
82                        rgb24[pos1 + 1] = temp;
83
84                        temp = rgb24[pos + 2];
85                        rgb24[pos + 2] = rgb24[pos1 + 2];
86                        rgb24[pos1 + 2] = temp;
87                    }

88                }

89            }

90            return true;
91        }

92    }

你可能感兴趣的:(windows,filter,table,mobile,dll,byte)