打印
[MCU]

关于LCD的多种颜色比例混合计算

[复制链接]
424|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
shipeng1989|  楼主 | 2020-5-9 15:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人突发奇想:可否将LCD字模按需求比例缩小显示,从而将所有大小的字体共用一套点阵数据表。这么做还有一个好处就是缩放显示小字体的时候字体边缘会有灰度效果从而视觉上会比较柔和。当然要做到这个柔和的效果需要通过算法检测字体边缘并根据边缘笔画的粗细计算颜色的灰度。乍一听可能大家会以为这套算法很厉害的样子,甚至于担心单片机会不会运算不过来?其实不然我举个例子你就知道了:

例如我想将32*32字体和16*16字体共用一套点阵数据表,那我应该怎么做呢?首先要做到字体边缘更和谐点阵数据表当然要用32*32的。接下来我们要怎么显示16*16的字体呢?其实也很简单就是拿到目标字符的32*32点阵数据后,每次X方向取两个像素同时Y方向也要取两个像素的数据。再根据取到的这4个像素数据计算你要点亮像素的颜色,如果这4个像素都为0那就显示背景色,4个像素1个=1,3个=0就根据公式:混合后红色分量 =(字体色红色分量*1+背景色红色分量*3)/(1+3),混合后绿色分量 =(字体色绿色分量*1+背景色绿色分量*3)/(1+3),混合后蓝色分量 =(字体色蓝色分量*1+背景色蓝色分量*3)/(1+3)。另外还有2个像素为1,2个为0;3个像素为1,1个为0;4个像素都为1;等情况依此类推最后将计算得到的混合后红/绿/蓝色分量进行混合即得到你要点亮的那个像素的颜色。

以下是实现该功能的源代码:

static uint16_t CalcMixedColor(uint16_t c1,uint16_t c2,uint16_t i,uint16_t j)//__attribute__((section("RAMCODE")))
{
    uint16_t r,g,b;
    b =((c1&0x1F)*i + (c2&0x1F)*j)/(i+j);
    c1 >>= 5;c2>>= 5;
    g =((c1&0x3F)*i + (c2&0x3F)*j)/(i+j);
    c1 >>= 6;c2 >>= 6;
    r =((c1&0x1F)*i + (c2&0x1F)*j)/(i+j);
    return (r<<11|g<<5|b);
}
static void LCD_Show16x16sym(uint16_t x,uint16_t y,uint8_t blk,uint8_t seg,uint16_t f_c,uint16_t b_c)
{
    if (blk<0xB0 || seg<0xA1 || x>LCD_Width-16 || y>LCD_Height-16)return ;
    uint32_t font_buf[32];
    UINT br,chs_ofs=(94*(blk-0xB0)+seg-0xA1)*32*4;
    uint16_t color_pad[5];
    color_pad[0]=b_c;       color_pad[4]=f_c;
    color_pad[1]=CalcMixedColor(f_c,b_c,1,3);
    color_pad[2]=CalcMixedColor(f_c,b_c,2,2);
    color_pad[3]=CalcMixedColor(f_c,b_c,3,1);
    if (FR_OK!=f_lseek(&Font_dat,chs_ofs) || FR_OK!=f_read(&Font_dat,font_buf,32*4,&br))
    {
        for (uint16_t i=0;i<32;i++)font_buf[i]=0xFFFFFFFF;
    }
    if (f_c!=b_c)
    {
        LCD_SetWindows(x,y,x+16-1,y+16-1);
        for(uint16_t i=0;i<32;i++)
        {
            uint32_t temp[2];
            temp[0]=font_buf[i];
            temp[1]=font_buf[++i];
            for(uint16_t j=16;j>0;j--)
            {
                uint8_t pan=(temp[0]&1)+(temp[1]&1);
                temp[0]>>=1;temp[1]>>=1;
                pan += (temp[0]&1)+(temp[1]&1);
                LCD_WR_DATA(color_pad[pan]);
                temp[0]>>=1;temp[1]>>=1;
            }
        }
    }
    else
    {
        for(uint16_t i=0;i<16;i++)
        {
            uint32_t temp[2];
            temp[0]=font_buf[i*2];
            temp[1]=font_buf[i*2+1];
            for(uint16_t j=0;j<16;j++)
            {
                uint8_t pan=(temp[0]&1)+(temp[1]&1);
                temp[0]>>=1;temp[1]>>=1;
                pan += (temp[0]&1)+(temp[1]&1);
                if(pan!=0)LCD_DrawPoint(x+j,y+i,color_pad[pan]);
                temp[0]>>=1;temp[1]>>=1;
            }
        }
    }
}
现在有个问题我解释不通:当字体色是黑色背景色为淡蓝色时是有预想的效果的,但把字体色换为红色后不知道为何字体边缘会出现黑色?

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

134

帖子

1

粉丝