在與硬件的藍牙通訊過程中,硬件需要手機端發(fā)送16*16的漢字點陣過去导帝,用于硬件直接顯示漢字路狮。這里采用的是通用的HZK16(宋體)漢字
原理
1.HZK16字庫是符合GB2312國家標準的16×16點陣字庫,HZK16的GB2312-80支持的漢字有6763個,符號682個。其中一級漢字有 3755個,按聲序排列拭宁,二級漢字有3008個,按偏旁部首排列瓣俯。
我們在一些應用場合根本用不到這么多漢字字模杰标,所以在應用時就可以只提取部分字體作為己用。 HZK16字庫里的16×16漢字一共需要256個點來顯示彩匕,也就是說需要32個字節(jié)才能達到顯示一個普通漢字的目的腔剂。
我們知道一個GB2312漢字是由兩個字節(jié)編碼的,范圍為0xA1A1~0xFEFE驼仪。A1-A9為符號區(qū)掸犬,B0-F7為漢字區(qū)袜漩。每一個區(qū)有94個字符(注意:這只是編碼的許可范圍,不一定都有字型對應湾碎,比如符號區(qū)就有很多編碼空白區(qū)域)宙攻。
下面以漢字「我」為例,介紹如何在HZK16文件中找到它對應的32個字節(jié)的字模數(shù)據(jù)介褥。
前面說到一個漢字占兩個字節(jié)座掘,這兩個中前一個字節(jié)為該漢字的區(qū)號,后一個字節(jié)為該字的位號呻顽。其中雹顺,每個區(qū)記錄94個漢字,位號為該字在該區(qū)中的位置廊遍。所以要找到「我」在hzk16庫中的位置就必須得到它的區(qū)碼和位碼。
區(qū)碼:漢字的第一個字節(jié)-0xA0贩挣,因為漢字編碼是從0xA0區(qū)開始的喉前,所以文件最前面就是從0xA0區(qū)開始,要算出相對區(qū)碼
位碼:漢字的第二個字節(jié)-0xA0
這樣我們就可以得到漢字在HZK16中的絕對偏移位置:offset = (94*(區(qū)碼-1)+(位碼-1))*32王财。
注解:
區(qū)碼減1是因為數(shù)組是以0為開始而區(qū)號位號是以1為開始的
(94*(區(qū)號-1)+位號-1)是一個漢字字模占用的字節(jié)數(shù)
最后乘以32是因為漢字庫文應從該位置起的32字節(jié)信息記錄該字的字模信息(前面提到一個漢字要有32個字節(jié)顯示)
以上是摘抄自HZK16漢字16*16點陣字庫的使用及示例程序 - 陪她去流浪
下面開始說明手機端如何發(fā)送(這里已OC為例卵迂,其他語言可自行進行修改)
首先需要先將UTF-8編碼轉換成 cp936 編碼,然后才能正確地索引字庫中的漢字绒净。
-(Byte *)convertStringToGBKStr:(NSString *)str{? ?
//轉換成UTF-8? ?
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);? ? NSData *data = [str dataUsingEncoding: enc];? ? Byte * bytes = (Byte *)[data bytes];? ? return bytes;
}
首先要確定硬件那邊的取模方式
下面的方法執(zhí)行完之后 會打印出來二進制 橫向掃描的0见咒,1的點陣
注意:這個0.1點陣字節(jié)為正序的。而實際硬件需要的字節(jié)需要倒序
- (void)sendText:(NSString *)str{?? ??? ?? ?
FILE* fphzk = NULL;?
? int offset;? ?
unsigned char buffer[32];? ?
unsigned char key[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };? ?
unsigned char word[3]; // 改成你的轉碼后的漢字編碼//? ?
? ?//文件路徑? ?
NSString *path = [[NSBundle mainBundle] pathForResource:@"HZK16" ofType:@""];? ? fphzk = fopen(path.UTF8String, "rb");?
? if(fphzk == NULL){? ? ?
? fprintf(stderr, "error hzk16\n");? ? ? ?
return;?
? }? ?
? ? ? ?//循環(huán)解碼? ?
NSMutableString *sendStr = [NSMutableString string];?
?for (int i=0; i<str.length; i++) {?? ? ? ?? ? ? ?
NSString *endStr = [str substringWithRange:NSMakeRange(i, 1)];? ?
?Byte *bytes = [self convertStringToGBKStr:endStr];? ? ? ? //漢字ascii編碼? ? ? ? //0xCE, 0xD2? ? ? ?
word[0] = bytes[0];? ? ?
word[1] = bytes[1];? ? ? ?
offset = (94*(unsigned int)(word[0]-0xa0-1)+(word[1]-0xa0-1))*32;? ?
fseek(fphzk, offset, SEEK_SET);? ? ? ?
fread(buffer, 1, 32, fphzk);? ? ?
for(k=0; k<16; k++){?
for(j=0; j<2; j++){?
? ?for(i=0; i<8; i++){?
? ? ? flag = buffer[k*2+j]&key[i];?
? ? ? printf("%s", flag?"1":"0");?
? ? ?}?
}?
printf("\n");?
? ? }
fclose(fphzk);
fphzk = NULL;
}
更多關于手機端發(fā)送16*16漢字點陣取模相關問題(二) - 簡書