IOS Emoji 编码打印

最新在研究下IOS的emoji。主要目的是想android ,wphone,symbian都同步支持ios 的emoji。因此设及到图库及表情定义符。在已有的emoji表情库里目前已知道记录的就很800多个,IOS 5 中集成的有479个。而IOS6 又新增了300个左右。


IOS 5 内部显示EMOJI使用提UTF16 编码。


先来看一段代码:

[plain] view plain copy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. <span style="color:#ff0000;">#define MAKE_Q(x) @#x  
  4. #define MAKE_EM(x,y) MAKE_Q(x##y)  
  5. #define MAKE_EMOJI(x) MAKE_EM(\U000,x)  
  6. #define EMOJI_METHOD(x,y) + (NSString *)x { return MAKE_EMOJI(y); } //method implementions at .m file  
  7. #define EMOJI_HMETHOD(x) + (NSString *)x;   //method define at .h file  
  8. #define EMOJI_CODE_TO_SYMBOL(x) ((((0x808080F0 | (x & 0x3F000) >> 4) | (x & 0xFC0) << 10) | (x & 0x1C0000) << 18) | (x & 0x3F) << 24);</span>  
  9.   
  10. @interface Emoji : NSObject  
  11. + (NSString *)emojiWithCode:(int)code;  
  12. + (NSArray *)allEmoji;  
  13. @end  

[plain] view plain copy
  1. #import "Emoji.h"  
  2. #import "EmojiEmoticons.h"  
  3. #import "EmojiMapSymbols.h"  
  4. #import "EmojiPictographs.h"  
  5. #import "EmojiTransport.h"  
  6.   
  7. @implementation Emoji  
  8. + (NSString *)emojiWithCode:(int)code {  
  9.     int sym = <span style="color:#ff0000;">EMOJI_CODE_TO_SYMBOL</span>(code);  
  10.     return [[NSString alloc] initWithBytes:&sym length:sizeof(sym) encoding:NSUTF8StringEncoding];  
  11. }  
  12. + (NSArray *)allEmoji {  
  13.     NSMutableArray *array = [NSMutableArray new];  
  14.     [array addObjectsFromArray:[EmojiEmoticons allEmoticons]];  
  15.     [array addObjectsFromArray:[EmojiMapSymbols allMapSymbols]];  
  16.     [array addObjectsFromArray:[EmojiPictographs allPictographs]];  
  17.     [array addObjectsFromArray:[EmojiTransport allTransport]];  
  18.       
  19.     return array;  
  20. }  
  21. @end  

[plain] view plain copy
  1. #import <Foundation/Foundation.h>  
  2. #import "Emoji.h"  
  3.   
  4. @interface EmojiEmoticons : NSObject  
  5.   
  6. + (NSArray *)allEmoticons;  
  7.   
  8. EMOJI_HMETHOD(grinningFace);  
。。。。
[plain] view plain copy
  1. #import "EmojiEmoticons.h"  
  2.   
  3. @implementation EmojiEmoticons  
  4.   
  5. + (NSArray *)allEmoticons {  
  6.     NSMutableArray *array = [NSMutableArray new];  
  7.     for (int i=0x1F600; i<=0x1F64F; i++) {  
  8.         if (i < 0x1F641 || i > 0x1F644) {  
  9.             [array addObject:[Emoji emojiWithCode:i]];  
  10.         }  
  11.     }  
  12.     return array;  
  13. }  
  14.   
  15. EMOJI_METHOD(grinningFace,1F600);  

以上代码是我从网上DOWN的一位老外写的,这段代码其它是遍历将编码进行组合成数组。主要看的是
[plain] view plain copy
  1. <span style="color:#ff0000;">#define EMOJI_CODE_TO_SYMBOL(x) ((((0x808080F0 | (x & 0x3F000) >> 4) | (x & 0xFC0) << 10) | (x & 0x1C0000) << 18) | (x & 0x3F) << 24);</span>  
这个宏的作用。它实际上是将一个Uindoe码转为UTF8。其中灵活的运用了位运算,此算法我还没有推导出他的计算规律,估且放一边,后面我会讲到一些UTF8及大于0x10000的UNICODE码转UTF16等算法。这里先看看遍历出来后Emoji的效果图;



呵呵,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码;

 #define MULITTHREEBYTEUTF16TOUNICODE(x,y) (((((x ^ 0xD800) << 2) | ((y ^ 0xDC00) >> 8)) << 8) | ((y ^ 0xDC00) & 0xFF)) + 0x10000 

当然这里还有大尾,小尾的区分,我这里就不再说明了,具体学习参考:http://zh.wikipedia.org/wiki/UTF-16



IOS 的提取代码:需实现UITextViewDelegate委托

[plain] view plain copy
  1. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text  
  2. {  
  3.     NSString *hexstr = @"";  
  4.   
  5.     for (int i=0;i< [text length];i++)  
  6.     {  
  7.         hexstr = [hexstr stringByAppendingFormat:@"%@",[NSString stringWithFormat:@"0x%1X ",[text characterAtIndex:i]]];  
  8.     }  
  9.     NSLog(@"UTF16 [%@]",hexstr);  
  10.       
  11.     hexstr = @"";  
  12.       
  13.     int slen = strlen([text UTF8String]);  
  14.       
  15.     for (int i = 0; i < slen; i++)   
  16.     {  
  17.         //fffffff0 去除前面六个F & 0xFF   
  18.         hexstr = [hexstr stringByAppendingFormat:@"%@",[NSString stringWithFormat:@"0x%X ",[text UTF8String][i] & 0xFF ]];  
  19.     }  
  20.     NSLog(@"UTF8 [%@]",hexstr);  
  21.       
  22.     hexstr = @"";  
  23.       
  24.     if ([text length] >= 2) {  
  25.           
  26.         for (int i = 0; i < [text length] / 2 && ([text length] % 2 == 0) ; i++)   
  27.         {  
  28.             // three bytes  
  29.             if (([text characterAtIndex:i*2] & 0xFF00) == 0 ) {  
  30.                 hexstr = [hexstr stringByAppendingFormat:@"Ox%1X 0x%1X",[text characterAtIndex:i*2],[text characterAtIndex:i*2+1]];  
  31.             }  
  32.             else  
  33.             {// four bytes    
  34.                 hexstr = [hexstr stringByAppendingFormat:@"U+%1X ",MULITTHREEBYTEUTF16TOUNICODE([text characterAtIndex:i*2],[text characterAtIndex:i*2+1])];      
  35.             }  
  36.               
  37.         }  
  38.         NSLog(@"(unicode) [%@]",hexstr);  
  39.     }  
  40.     else  
  41.     {  
  42.         NSLog(@"(unicode) U+%1X",[text characterAtIndex:0]);  
  43.     }  
  44.       
  45.     return YES;  
  46. }  

上面代码搞好后在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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值