继续介绍单片机的抗锯齿方法实现

admin 2017-6-24 4046


首先,在上贴中提到需要准备一副含有黑纸白字的图片,如下

然后用彩色字模读取数据

注意这里选择256灰阶,如果内存小的话,也可以取16灰阶,不过最大的抗锯齿就只能到16,如果是256阶的话,抗锯齿级别可以是256,128,64,62,16,4,2,这在后面的程序中会介绍。这也是gui的抗锯齿级别。

建议最好别小于16。16比256的数据量小一倍,相当于一个字节保存两个数据点。

然后开始写程序,我这边没有用画点函数drawpoint,而是直接用显示器的buffer。

 void Char_UbuntuMono_16(int x, int y, unsigned char c, unsigned short color, unsigned short back_color)
 {//12*32 = 384 wide
  //26*5 =  130 high
    unsigned int i, j, factor;
    unsigned char alpha;
    float alpha_factor;
    unsigned char color_R,color_G,color_B;
    unsigned char back_color_R,back_color_G,back_color_B;
    
    color_R = color >> 11 << 3;
    color_G = color << 5 >> 10 << 2;
    color_B = color << 3;
    
    back_color_R = back_color >> 11 << 3;
    back_color_G = back_color << 5 >> 10 << 2;
    back_color_B = back_color << 3;
    
    if(c < 128)    c = c - ' ';
    else           c = c - 96;
    
    factor = c/32;
    
    for(i = 0;i < 26; i++){
        for(j = 0; j < 12; j++){
           alpha = font_16[384*(factor*26 + i) + (c - factor*32)*12 + j];//>>4
           if(alpha == 255/*15*/) frambuf[800*(i + x) + j + y] = color;
           else if(alpha == 0)    frambuf[800*(i + x) + j + y] = back_color;
           else{
               alpha_factor = 1.0*alpha/255/*15*/;
               frambuf[800*(i + x) + j + y] = (((char)(alpha_factor*(color_R - back_color_R)) + back_color_R) >> 3) << 11 |
                                              (((char)(alpha_factor*(color_G - back_color_G)) + back_color_G) >> 2) <<  5 |
                                              (((char)(alpha_factor*(color_B - back_color_B)) + back_color_B) >> 3) ;
           }
        }
    }
 }

这是显示一个字符的函数,color_R,color_G,color_B是先将RGB565的数据拆分为R、G、B,背景色同理。

alpha 就是我们刚才存储的数据像素点的值。

alpha_factor*(color_R - back_color_R)) + back_color_R这个公式我解释一下,像素点的颜色=(alpha/255)*color + (255 - alpha)*back_color,转换下就是(alpha/255)*(color - back_color) + back_color;

然后将R/G/B分量各自计算出来,最后按位或成565数据。

因为数据中其实大部分都是255和0,为了显示提高显示速度和节省CPU资源,就将他们分别列出来

  if(alpha == 255/*15*/) frambuf[800*(i + x) + j + y] = color;
  else if(alpha == 0)    frambuf[800*(i + x) + j + y] = back_color;

前面提到过抗锯齿级别,我这里直接用的是255级别,直接写死了,如果需要调节锯齿级别,需要自己定义一个级别数,修改三个地方即可(我已经在注释/* */里把16级别的写出来了)。

字符串函数还是那样写

 void String_UbuntuMono_16(int x,int y, unsigned char *str, unsigned short color, unsigned short back_color)
 {
    unsigned char *p = str;
    while (*p != 0){
        Char_UbuntuMono_16(x, y, *p, color, back_color);
        y = y + 12;
        p++; 
    }
 }


最后显示一下带有抗锯齿功能的字体

    String_UbuntuMono_16(200, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", COLOR_WHITE, COLOR_BACK_GROUND);
    String_UbuntuMono_16(230, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", COLOR_GREEN, COLOR_WHITE);
    String_UbuntuMono_16(260, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", COLOR_RED, COLOR_BLUE);
    String_UbuntuMono_16(290, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", COLOR_YELLOW, COLOR_BLACK);

显示如下

转自:https://www.amobbs.com/thread-5676479-1-1.html


最新回复 [1]
  • admin 2017-6-27
    0 2

     如果需要显示透明字符,需要改动如下

    void Char_UbuntuMono_16(int x, int y, unsigned char c, unsigned short color)
    {//12*32 = 384 wide
      //26*5 =  130 high
        unsigned int i, j, factor;
        unsigned char alpha;
        float alpha_factor;
        unsigned char color_R,color_G,color_B;
        unsigned short int back_color;
        unsigned char back_color_R,back_color_G,back_color_B;
        
        color_R = color >> 11 << 3;
        color_G = color << 5 >> 10 << 2;
        color_B = color << 3;
        
        if(c < 128)    c = c - ' ';
        else           c = c - 96;
        
        factor = c/32;
        
        for(i = 0;i < 26; i++){
            for(j = 0; j < 12; j++){
               alpha = font_16[384*(factor*26 + i) + (c - factor*32)*12 + j];//>>4
               if(alpha == 255/*15*/) frambuf[800*(i + x) + j + y] = color;
               else if(alpha == 0);//显示为原来的背景色,不做改变。
               else{
                   back_color =  frambuf[800*(i + x) + j + y];//取当前背景颜色为back_color。
                      back_color_R = back_color >> 11 << 3;
                     back_color_G = back_color << 5 >> 10 << 2;
                     back_color_B = back_color << 3;
                   alpha_factor = 1.0*alpha/255/*15*/;
                   frambuf[800*(i + x) + j + y] = (((char)(alpha_factor*(color_R - back_color_R)) + back_color_R) >> 3) << 11 |
                                                  (((char)(alpha_factor*(color_G - back_color_G)) + back_color_G) >> 2) <<  5 |
                                                  (((char)(alpha_factor*(color_B - back_color_B)) + back_color_B) >> 3) ;
               }
            }
        }
    }


返回