我们平常在微信等平台上聊天时,一般都会发一些表情来替代文字,这些从广义来说都可以成为Emoji表情,都是用图片表情来表达文字信息,增加了表达方式,契合年轻化人的性格。正因此才大受欢迎。如果从严谨来看,只有手机系统内置的表情才算emoji表情,因为这些表情是以字体编码的方式规范到unicode编码集里面的。
什么是字体编码
计算机存储都是以二进制的形式的,也就是说所有的文字都是以以二进制的数字存储的。简单来说我们需要一个文字和数字的转换字典,用以存储和显示文字,比如英文中的A存储在二进制的数字是65。那么他应该存储的时候就是把A变成65,再装换成二进制0100 0001, 下次取到到这个值0100 0001的时候就知道对应的是字母A。(在编程语言中A和65是可以互相转换的)
ASCII码
计算机诞生于美国,上面提到A的二进制的数字形式是65,但是实际上也可以是其他的数字,这里的数字只是相当于一个身份标记,因此需求进行统一的一套字体数字字典,美国有一个叫做美国国家标准学会(American National Standard Institute , ANSI ),根据当时使用到的英语和其他常用字符,组建了一套字体编码字典,称为ASCII码,如下图
列举了部分ASCII字体编码
字符 | 说明 | 十进制 | 二进制 |
---|---|---|---|
A | 大写字母A | 65 | 0100 0001 |
a | 小写字母A | 97 | 0100 0001 |
0 | 阿拉伯数字0 | 48 | 0011 0000 |
! | 感叹号 | 33 | 0010 0001 |
起初设计字体编码表的时候只考虑到了英文和一些特殊字符,总共128个,因此ASCII只有128个字体。 如下图,图片来源百度百科。
Unicode编码
unicode编码这里不做详述,其实就是把世界各国的语言文字整理称一个统一的规范,这样便于不同计算机系统的语言通信。
Emoji表情
随着表达方式的发展,仅用文字表达方式比较单一,人们就试图用一些小图标可以俏皮的展示当前的心情,增加互动的趣味,因此,Emoji表情就诞生了,如下图是苹果系统的一些Emoji表情。
值得一提的是,目前我们使用的微信的表情符号是涵盖了Emoji表情和微信表情的,新增的的一些表情包是微信APP自带识别和转换的,系统自带的emoji表情后面已经归入到Unicode编码里面,而微信的表情是微信APP识别和转换的。区别也很容易,就是我们在输入法里面能使用的表情在其他软件里也可以输入,但是微信自带的表情是其他app识别不了的。
Mysql存储Emoji表情报错
前面提到,原先的128个数字已经不够用了,因此新增了Unicode编码标准,而UTF-8是Unicode标准的具体实现。标准的定义类似于上头批示了红头文件,实现类似于下面的人根据文件指示实际的干活。UTF-8在存储文字的时候是可以使用1-4个字节的。而Mysql在5.5.3版本之前的UTF-8只使用了3个字节,而Emoji表情是后面加入到Unicode标准里面的,所以5.5.3之前的mysql不支持存储emoji表情,会报错,比如java存储时会报以下错误。
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x94\xA5' for column
解决方法
- 如果mysql是5.5.3以上版本的,修改库或者表或者列的字符集为utf8mb4。具体可以百度。
- 使用Emoji表情解析类框架来存储
java种的Emoji表情存储框架
目前用的较多的时Emoji-Java这个框架。
github地址为https://github.com/vdurmont/emoji-java。
简单使用
String str = "An 😀awesome 😃string with a few 😉emojis!";
//用于存储mysql时的转换
String htmlStr = EmojiParser.parseToHtmlDecimal(str);
System.out.println("emoji转换成别名: " + htmlStr);
//从mysql中取出后在转换回来
String unicode = EmojiParser.parseToUnicode(htmlStr);
System.out.println("emoji别名在转换回来: " + unicode);
打印
emoji转换成别名: An 😀awesome 😃string with a few 😉emojis!
emoji别名在转换回来: An 😀awesome 😃string with a few 😉emojis!
此外,该框架还有其他的用途,比如去除字符串中的Emoji表情或者找出表情等等功能。
Emoji解析框架实现原理比较简单,但是需要耗费较多时间,本质上就是在存储emoji表情时转换成一个别名,比如😁这个表情,我们把它用 [微笑] 来存储,这就做到了别名,存储时就是存储的 [微笑] ,等从数据库种取出来时候,在转换成字符编码(U+1F601),这样就可以完成了转换了。