前段时间在新的平台上测试,由于没有实际的图像源,所以在内存填充颜色彩条来临时作为图像。下面给出实现代码。
1、用SDL显示的代码,RGB888格式:
思路很简单:将整个画面填充10种颜色,使用line的效率很低,不过,作为演示代码也可以了。
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;
}
}
{
// 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格式,填充缓冲区
/// 填充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);
}
}
}
#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);
}
}
}
4、UYVY格式,填充缓冲区
其中rgb2YCbCr用于将RGB转换成YUV。
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
}
}
}
{
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