填充颜色彩条

前段时间在新的平台上测试,由于没有实际的图像源,所以在内存填充颜色彩条来临时作为图像。下面给出实现代码。

1、用SDL显示的代码,RGB888格式:

思路很简单:将整个画面填充10种颜色,使用line的效率很低,不过,作为演示代码也可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void show_rainbow()
{
    // 0x7FFF00, 0xFF7D40, 0xFF00FF,
    unsigned int rgbColor[] = {0xFF0000, 0xFF6100, 0xFFFF00, 0x00FF00, 0x00FFFF, 
        0x0000FF, 0xA020F0, 0x000000, 0xFFFFFF, 0xF4A460};

    int cnt = sizeof(rgbColor)/sizeof(rgbColor[0]);
    int y = 0, u = 0, v = 0;
    int k = 0;
    for (int i = 0; i < cnt; i++)
    {
        for (int j = 0; j <  WINDOW_HEIGHT / 10; j++)
            line(0, 0 + k + j, WINDOW_WIDTH-1, 0 + k + j, rgbColor[i]);
            //line(0 + k + j, 0, 0 + k + j, WINDOW_HEIGHT - 1, rgbColor[i]);
        k += WINDOW_HEIGHT / 10;
    }
}

2、RGB格式,填充缓冲区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// 填充RGB数据,格式:RGB565 

#define WIDTH 720
#define HEIGHT 480
static unsigned char my_buf[WIDTH*HEIGHT*2] = {0};

static void init_my_buf(int width, int height)
{
    unsigned char *src = my_buf;
    int i, j;

    // 10种颜色的RGB表
    unsigned int rainbow_rgb[] = {
    0xFF0000, 0xFF6100, 0xFFFF00, 0x00FF00, 0x00FFFF,
    0x0000FF, 0xA020F0, 0x000000, 0xFFFFFF, 0xF4A460};

    int slice = height/10;

    for (i = 0; i < height; i++)
    {
        int index = i / slice;
        // 转换成RGB565
        unsigned short color = fb_rgb565(rainbow_rgb[index]);

        for (j=0; j<width * 2; j+=2)
        {
            // 方法1
            *((unsigned short*)(src + i*width * 2 + j)) = color;
            // 方法2
            //src[i*720*2 + j+0] = (unsigned char)(color & 0x00ff);
            //src[i*720*2 + j+1] = (unsigned char)((color & 0xff00) >> 8);
        }
    }
}

3、UYVY格式,填充缓冲区

其中rgb2YCbCr用于将RGB转换成YUV。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
int rgb2YCbCr(unsigned int rgbColor, int* Y, int* Cb, int* Cr)
{
    unsigned char r, g, b;
    int y, cb, cr;
    r = (rgbColor&0x00ff0000) >> 16;
    g = (rgbColor&0x0000ff00) >> 8;
    b = rgbColor & 0xff;

    y = (int)( 0.299    * r + 0.587   * g + 0.114   * b);
    cb = (int)(-0.16874 * r - 0.33126 * g + 0.50000 * b + 128);
    if (cb < 0)
        cb = 0;
    cr = (int)( 0.50000 * r - 0.41869 * g - 0.08131 * b + 128);
    if (cr < 0)
        cr = 0;

    *Y = y;
    *Cb = cb;
    *Cr = cr;

    return 0;
}

#define WIDTH 720
#define HEGHT 480

static unsigned char g_buf[WIDTH * HEGHT * 2] = {0x80};

/// 填充YUV数据,格式:UYVY
static void init_my_buf(int width, int height)
{
    unsigned char *src = g_buf;
    int i, j;

    unsigned int rainbow_rgb[] = {
    0xFF0000, 0xFF6100, 0xFFFF00, 0x00FF00, 0x00FFFF,
    0x0000FF, 0xA020F0, 0x000000, 0xFFFFFF, 0xF4A460};

    unsigned int rainbow_yuv[] = {
    0x4c54ff, 0x8534d6, 0xe10094, 0x952b15, 0xb2ab00,
    0x1dff6b, 0x5dd2af, 0xbb1654, 0x9c4bc5, 0xb450ad};

    int slice = height / 10;
    for (i = 0; i < height; i++) // h
    {
        int index = i / slice;
        unsigned char y = (rainbow_yuv[index] & 0xff0000 ) >> 16;
        unsigned char u = (rainbow_yuv[index] & 0x00ff00) >> 8;
        unsigned char v = (rainbow_yuv[index] & 0x0000ff);
        for (j=0; j<width*2; j+=4)    // w
        {
            src[i*width*2+j+0] = u; // U
            src[i*width*2+j+1] = y; // Y0
            src[i*width*2+j+2] = v; // V
            src[i*width*2+j+3] = y; // Y1
        }
    }
}

重点是如何填充数据区,其实,只要了解所需的格式要求,就可以进行填充了。比如,RGB565格式,就是1个像素占2个字节,于是直接用强转就行了。而UYVY格式的,就是分别得到Y、U、V数据,依次填充。

迟 匆忙于2013-03-20