IOS 5 内部显示EMOJI使用提UTF16 编码。
先来看一段代码:
- #import <Foundation/Foundation.h>
- <span style="color:#ff0000;">#define MAKE_Q(x) @#x
- #define MAKE_EM(x,y) MAKE_Q(x##y)
- #define MAKE_EMOJI(x) MAKE_EM(\U000,x)
- #define EMOJI_METHOD(x,y) + (NSString *)x { return MAKE_EMOJI(y); } //method implementions at .m file
- #define EMOJI_HMETHOD(x) + (NSString *)x; //method define at .h file
- #define EMOJI_CODE_TO_SYMBOL(x) ((((0x808080F0 | (x & 0x3F000) >> 4) | (x & 0xFC0) << 10) | (x & 0x1C0000) << 18) | (x & 0x3F) << 24);</span>
- @interface Emoji : NSObject
- + (NSString *)emojiWithCode:(int)code;
- + (NSArray *)allEmoji;
- @end
- #import "Emoji.h"
- #import "EmojiEmoticons.h"
- #import "EmojiMapSymbols.h"
- #import "EmojiPictographs.h"
- #import "EmojiTransport.h"
- @implementation Emoji
- + (NSString *)emojiWithCode:(int)code {
- int sym = <span style="color:#ff0000;">EMOJI_CODE_TO_SYMBOL</span>(code);
- return [[NSString alloc] initWithBytes:&sym length:sizeof(sym) encoding:NSUTF8StringEncoding];
- }
- + (NSArray *)allEmoji {
- NSMutableArray *array = [NSMutableArray new];
- [array addObjectsFromArray:[EmojiEmoticons allEmoticons]];
- [array addObjectsFromArray:[EmojiMapSymbols allMapSymbols]];
- [array addObjectsFromArray:[EmojiPictographs allPictographs]];
- [array addObjectsFromArray:[EmojiTransport allTransport]];
- return array;
- }
- @end
- #import <Foundation/Foundation.h>
- #import "Emoji.h"
- @interface EmojiEmoticons : NSObject
- + (NSArray *)allEmoticons;
- EMOJI_HMETHOD(grinningFace);
- #import "EmojiEmoticons.h"
- @implementation EmojiEmoticons
- + (NSArray *)allEmoticons {
- NSMutableArray *array = [NSMutableArray new];
- for (int i=0x1F600; i<=0x1F64F; i++) {
- if (i < 0x1F641 || i > 0x1F644) {
- [array addObject:[Emoji emojiWithCode:i]];
- }
- }
- return array;
- }
- EMOJI_METHOD(grinningFace,1F600);
以上代码是我从网上DOWN的一位老外写的,这段代码其它是遍历将编码进行组合成数组。主要看的是
- <span style="color:#ff0000;">#define EMOJI_CODE_TO_SYMBOL(x) ((((0x808080F0 | (x & 0x3F000) >> 4) | (x & 0xFC0) << 10) | (x & 0x1C0000) << 18) | (x & 0x3F) << 24);</span>
呵呵,IOS的控件已帮我们自动的将UTF8或UTF16码进行转为相应的图片了,对IOS来说,图片资源就不用再让UCD出了或网上COPY了。
对于android ,wphone,symbian目前都没有很好的支持UNICODE 中的emoji。因此在做应用时需要各自的对照库及图片库。要完全兼容于IOS 6。哪务必要知道IOS 6中的各个emoji及其它表情符的编码定义,网上搜了好些都没有完整的编码定义及表情。没有办法,只硬着头皮上,把IOS6的全部导出来。话说干就干。
不过干之前先来了解一下基本知识(编码转换)。
Unicode | U+1F1F7 U+1F1FA | U+1F1EC U+1F1E7 | U+1F1E9 U+1F1EA | ||||||||
UTF8 | 0xF0 0x9F 0x87 0xB7 0xF0 0x9F 0x87 0xBA | 0xF0 0x9F 0x87 0xAC 0xF0 0x9F 0x87 0xA7 | 0xF0 0x9F 0x87 0xA9 0xF0 0x9F 0x87 0xAA | ||||||||
UTF16 | 0xD83C 0xDDF7 0xD83C 0xDDFA | 0xD83C 0xDDEC 0xD83C 0xDDE7 | 0xD83C 0xDDE9 0xD83C 0xDDEA | ||||||||
SB Unicode | E512 | E510 | E50E |
UTF-16 编码程序
假设要将 U+64321 (16进位) 转成 UTF-16 编码. 因为它超过 U+FFFF, 所以他必须编译成32位(4个byte)的格式,如下所示:11
V = 0x64321 Vx = V - 0x10000 = 0x54321 = 0101 0100 0011 0010 0001 Vh = 01 0101 0000 // Vx 的高位部份的 10 bits Vl = 11 0010 0001 // Vx 的低位部份的 10 bits w1 = 0xD800 //結果的前16位元初始值 w2 = 0xDC00 //結果的後16位元初始值 w1 = w1 | Vh = 1101 1000 0000 0000 | 01 0101 0000 = 1101 1001 0101 0000 = 0xD950 w2 = w2 | Vl = 1101 1100 0000 0000 | 11 0010 0001 = 1101 1111 0010 0001 = 0xDF21
所以这个字 U+64321 最后正确的 UTF-16 编码应该是:
0xD950 0xDF21
而在小尾序中最后的编码应该是:
0x50D9 0x21DF
按照这个算法,我们来推算一下U+1F604 利用推算来映射出位操作(位操作不是很熟的朋友可网上学习学习)。
0x1F604 = 0001 1111 0110 0000 0100 (二进制)
0x1F604 - 0x10000 = 0xF604 = 1111 0110 0000 0100
分别取0xF604 的高十位和低十位(不足的补0)
Vh = 00 0011 1101 = 0x3D (高位)
Vl = 10 0000 0100 = 0x204 (低位)
然后取高位与前十六位初始元0xD800 进行或操作后为作UTF16的前部份
取低位与后十六位初始元0xDC00进行或操作后作为UTF16的后半部份。
0x3D | 0xD800 = 0xD83D
0x204 | 0xDC00 = 0xDE04
所以U+1F604 的UTF16 为0xD83D 0xDE04
假设要处理的UNICODE编码为X,来推一下位运算公式
第一步:X - 0x10000 得到结果为Y
第二步:取Y的高十位:Y >> 10 得到结果为Vh
第三步:取Y的低十位:Y & 3FF(11 1111 1111) 这样就可以把十位前的全部清零了。 得到结果为Vl
第四步:将高位与前16位初始元0xD800 进行或操作 Vh | 0xD800 得到前半部 记为Uf
第五步:将低位与后16位初始元0xDC00进行或操作Vl |0xDC00 得到后半部份。Ue
第六步:将前后两部份合在一起。先左移十六位 (Uf << 16) 再或上Ue 即 (Uf << 16) | Ue
把这个写为宏的形式:
#define UNICODETOUTF16(x) ((Uf << 16) | Ue) 将这个公式向前代替,最终得到
#define UNICODETOUTF16(x) (((((x - 0x10000) >>10) | 0xD800) << 16) | (((x-0x10000)&3FF) | 0xDC00))
同样使用UTF16转回为大于0x10000 的Unicode码;
当然这里还有大尾,小尾的区分,我这里就不再说明了,具体学习参考:http://zh.wikipedia.org/wiki/UTF-16
IOS 的提取代码:需实现UITextViewDelegate委托
- - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
- {
- NSString *hexstr = @"";
- for (int i=0;i< [text length];i++)
- {
- hexstr = [hexstr stringByAppendingFormat:@"%@",[NSString stringWithFormat:@"0x%1X ",[text characterAtIndex:i]]];
- }
- NSLog(@"UTF16 [%@]",hexstr);
- hexstr = @"";
- int slen = strlen([text UTF8String]);
- for (int i = 0; i < slen; i++)
- {
- //fffffff0 去除前面六个F & 0xFF
- hexstr = [hexstr stringByAppendingFormat:@"%@",[NSString stringWithFormat:@"0x%X ",[text UTF8String][i] & 0xFF ]];
- }
- NSLog(@"UTF8 [%@]",hexstr);
- hexstr = @"";
- if ([text length] >= 2) {
- for (int i = 0; i < [text length] / 2 && ([text length] % 2 == 0) ; i++)
- {
- // three bytes
- if (([text characterAtIndex:i*2] & 0xFF00) == 0 ) {
- hexstr = [hexstr stringByAppendingFormat:@"Ox%1X 0x%1X",[text characterAtIndex:i*2],[text characterAtIndex:i*2+1]];
- }
- else
- {// four bytes
- hexstr = [hexstr stringByAppendingFormat:@"U+%1X ",MULITTHREEBYTEUTF16TOUNICODE([text characterAtIndex:i*2],[text characterAtIndex:i*2+1])];
- }
- }
- NSLog(@"(unicode) [%@]",hexstr);
- }
- else
- {
- NSLog(@"(unicode) U+%1X",[text characterAtIndex:0]);
- }
- return YES;
- }
上面代码搞好后在UITEXTVIEW中输入表情符,就会打印出相应的编码了。如果想进一步收集。只需要封装成自己想要的数据格式导出即可。
其中还有softbank的编码未搞懂,小日本的东西。
参考:
UNICODE标准,查找
http://www.unicode.org/
http://www.unicode.org/charts/
Emojin集合表(479):
http://punchdrunker.github.com/iOSEmoji/table_html/vehicle.html
DEMO:
http://download.csdn.net/detail/fengsh998/5137701
Unicode | U+1F1F7 U+1F1FA | U+1F1EC U+1F1E7 | U+1F1E9 U+1F1EA | ||||||||
UTF8 | 0xF0 0x9F 0x87 0xB7 0xF0 0x9F 0x87 0xBA | 0xF0 0x9F 0x87 0xAC 0xF0 0x9F 0x87 0xA7 | 0xF0 0x9F 0x87 0xA9 0xF0 0x9F 0x87 0xAA | ||||||||
UTF16 | 0xD83C 0xDDF7 0xD83C 0xDDFA | 0xD83C 0xDDEC 0xD83C 0xDDE7 | 0xD83C 0xDDE9 0xD83C 0xDDEA | ||||||||
SB Unicode | E512 | E510 | E50E |