2395|0

327

帖子

1

TA的资源

纯净的硅(初级)

楼主
 

关于LCD的多种颜色比例混合计算 [复制链接]

本帖最后由 shipeng 于 2020-5-9 15:24 编辑

本人突发奇想:可否将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;
			}
		}
	}
}


现在有个问题我解释不通:当字体色是黑色背景色为淡蓝色时是有预想的效果的,但把字体色换为红色后不知道为何字体边缘会出现黑色?

此帖出自单片机论坛
点赞 关注
个人签名模电临时工
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表