关于RGB888小端和RGB565大端互转代码实现方案

上一篇,原文链接:https://blog.csdn.net/qq_44829055/article/details/127022197中均是RGB888小端模式和RGB565小端模式的互转。这个适用于应用层处理。

本案例特别适用于LCD屏的RGB888小端原始数据转换为RGB565大端模式(LCD屏基本上均是大端模式)。

1、为什么RGB888要转RGB565呢,这个问题尤其在嵌入式lcd屏中,因为RGB888占用24位,RGB565占用16位及2个字节。

2、例如嵌入式中的LCD屏接口一般位IIC、SPI、8080等,如果传送RGB888每个像素点就要多送一个字节,320*240的LCD屏就要多送76800字节的数据。

3、我看到的一般驱动代码中均是将RGB888进行相与移位等操作得到R,G、B类似操作。速度慢代码不精简。如何优化呢,这里我就开门见山了,使用结构体就能很好解决RGB888和RGB565互转。单使用结构体还不够好,就把结构体和共用体结合了。

4、以下是测试部分,使用原始方案RGB888转RGB565,及原始方案RGB565转RGB888,及新的方案。不难发现新方案测试结果和旧方案一样。

5、至于速度方面我没有太研究过位域处理和计算处理的效能,但从代码结构上,位域更加清晰及精简。

6、备注:51单片机基本上均是大端模式。32位单片机及更高的大部分均是小端模式。

附加源码:

//作者:金丝草
//时间:2022/09/24

#include <iostream>



//这里重申下,RGB888为小端模式,RGB565为大端模式(外设SPI LCD屏均是大端模式的,有利于发送数据)

/***********************************RGB888 RGB565*************************************/
typedef union
{
    uint32_t RGB888;
    struct
    {
        uint32_t       :3;
        uint32_t RGB_B :5;
        uint32_t       :2;
        uint32_t RGB_G :6;
        uint32_t       :3;
        uint32_t RGB_R :5;
        uint32_t       :8;
    }Work;
}RGB888_struct;
typedef union
{
    uint16_t RGB565;
    struct
    {
        uint16_t RGB_R :5;
        uint16_t RGB_G :6;
        uint16_t RGB_B :5;
    }Work;
}RGB565_struct;

//输入一个RGB888的32位数据地址,返回转换后的RGB565
static uint16_t RGB888_To_RGB565(const RGB888_struct *RGB888)
{
    RGB565_struct RGB565 = { 0 };
    
    RGB565.Work.RGB_R = RGB888->Work.RGB_R;
    RGB565.Work.RGB_G = RGB888->Work.RGB_G;
    RGB565.Work.RGB_B = RGB888->Work.RGB_B;
    return RGB565.RGB565;
}
//输入一个RG565的16位数据地址,返回转换后的RGB888
static uint32_t RGB565_To_RGB888(const RGB565_struct *RGB565)
{
    RGB888_struct RGB888 = { 0 };

    RGB888.Work.RGB_R = RGB565->Work.RGB_R;
    RGB888.Work.RGB_G = RGB565->Work.RGB_G;
    RGB888.Work.RGB_B = RGB565->Work.RGB_B;
    return RGB888.RGB888;
}
/***********************************RGB888 RGB565*************************************/



static void test_RGB888_To_RGB565(void)
{
    uint32_t color888 = 0;
    uint32_t i;

    for (i = 1; i <= 50; i++)
    {
        printf("新RGB888->RGB565 =%5d  ", RGB888_To_RGB565((RGB888_struct*)&color888));
        color888 += 100;
        if ((i % 5) == 0)
            printf("\r\n");
    }
    printf("\r\n");
}
static void test_RGB565_To_RGB888(void)
{
    uint16_t color565 = 0;
    uint32_t i;

    for (i = 1; i <= 50; i++)
    {
        printf("新RGB565->RGB888 =%8d  ", RGB565_To_RGB888((RGB565_struct*)&color565));
        color565 += 100;
        if((i%5) == 0)
            printf("\r\n");
    }
    printf("\r\n");
}


int main()
{
    uint32_t test_data = 0;
    uint32_t i;
    uint32_t color888 = 0;
    uint16_t color565 = 0;

    uint8_t R = 0;
    uint8_t G = 0;
    uint8_t B = 0;


    for (i = 1; i <= 50; i++)//原始方案计算伤脑子
    {
        R = (color888 & 0xff0000) >> (16 + 3);
        G = (color888 & 0x00ff00) >> (8 + 2);
        B = (color888 & 0x0000ff) >> 3;
        //test_data = (R << (5 + 6)) | (G << 5) | B;
        test_data = (B << (5 + 6)) | (G << 5) | R;
        printf("旧test__888->565 =%5d  ", test_data);
        color888 += 100;
        if ((i % 5) == 0)
            printf("\r\n");
    }
    printf("\r\n");
    test_RGB888_To_RGB565();//新方案速度更快还不伤脑子

    for (i = 1; i <= 50; i++)//原始方案计算伤脑子
    {
        R = (color565 & 0xf800) >> (5 + 6);
        G = (color565 & 0x07e0) >> 5;
        B = (color565 & 0x001f) >> 0;
        //test_data = (R << (16 + 3)) | (G << 8 + 2) | (B << 3);
        test_data = (B << (16 + 3)) | (G << 8 + 2) | (R << 3);
        printf("旧test__565->888 =%8d  ", test_data);
        color565 += 100;
        if ((i % 5) == 0)
            printf("\r\n");
    }
    printf("\r\n");
    test_RGB565_To_RGB888();//新方案速度更快还不伤脑子



    std::cout << "Hello World!\n";
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金丝草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值