看了一個點陣的實現(xiàn)形式,感覺挺好的.對其中的技術(shù)點總結(jié)一下.
點陣的顯示原理
當字符或者圖片在點陣上需要顯示時,可以認為是數(shù)據(jù)源在對應(yīng)的像素點上的像素是有或者沒有.
如果有那么這一個像素點九顯示反之就不顯示.
那么需求就來了 如何得到資源數(shù)據(jù)(字符或者圖片)像素值(這個像素值應(yīng)該是個二位數(shù)組).
像素值的存放
在java中所有的數(shù)據(jù)底層都是byte(字節(jié)),字節(jié)數(shù)據(jù)可以存放到byte數(shù)組中.那么存放的問題就解決了
字符資源的存放
String.getBytes()
String.getBytes(Charset)
對于字符串數(shù)據(jù)可以通過上面的兩個方法獲取字節(jié)數(shù)組,但是不建議使用第一個,因為第一個會得到一個缺省編碼的字節(jié)數(shù)組.
通過設(shè)置特定的編碼格式,可以得到大小不同的字節(jié)
關(guān)于字符資源的轉(zhuǎn)換還有一些其他的點,也順便記錄一下.
*與getBytes對應(yīng)的可以通過設(shè)置編碼格式從字節(jié)數(shù)組創(chuàng)建一個新的字符串new String(byte[], Charset) 這里就要求以什么格式獲得的字節(jié)數(shù)組在返回字符串的時候必須設(shè)置同樣的編碼格式,否則就會得到亂碼的結(jié)果如圖所示 *
另外對于iso8859-1編碼的結(jié)果在返回的時候也會出現(xiàn)亂碼,這個是因為在ISO8859-1編碼的編碼表中就不存在漢字字符
因此在通過String.getBytes(Charset)和new String(byte[],Charset)進行轉(zhuǎn)換時需要注意當前的編碼格式的編碼表中存在目標String的碼值**
對于特殊需求一定需要使用ISO8859-1編碼格式的中文字符怎么辦呢比如(http header 要求其內(nèi)容必須時iso8859-1編碼)這個時候可以采用借雞生蛋的轉(zhuǎn)換方法
public static void main(String[] args) {
String str="我";
try {
byte[]str_gbk=str.getBytes("gbk");
byte[]str_utf8=str.getBytes("utf-8");
byte[]str_iso88591=str.getBytes("iso8859-1");
String reslut=new String(str_iso88591, "iso8859-1");
System.out.println(reslut);
System.out.println("----------------");
String resource=new String(str.getBytes("utf-8"), "iso8859-1");
String result1=new String(resource.getBytes("iso8859-1"), "utf-8");
System.out.println(result1);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
GB2312和GBK的關(guān)系
1.GBK 是GB2312的擴展
2.GB2312是中國規(guī)定的漢字的編碼 即簡體中文的編碼.而GBK
在兼容GB2312的基礎(chǔ)上還支持繁體字的顯示,同樣還有日文
的假名
HZK16字庫
1.HZK16字庫是符合GB2312標準的16*16的點陣字庫
2.HZK16的GB2312-80支持的漢字有6763個
符號682個其中一級漢字3755個 二級漢字3008個
到這里已經(jīng)得到了字符的資源了,這里先選擇使用gbk編碼格式原因下面在解釋.
兩個字節(jié)大小的字節(jié)數(shù)組里存的是什么
1.第一個字節(jié)放的就是該漢字的區(qū)號,第二個字節(jié)放的就是該漢字的位號
2.GB2312漢字有兩個字節(jié)編碼,范圍是0XA1A1~0XFEFE
其中A1-A9為符號區(qū) B0-F7為漢字區(qū)
3.以漢字 我 為例在HZK16字庫中找到它對應(yīng)的32個字節(jié)的子模數(shù)據(jù).
第一個字節(jié)為區(qū)號,后一個字節(jié)為位號.
其中每個區(qū)號記錄94個漢字,位號為該漢字在該區(qū)中的位置,所以要找到這個漢字就必須找到它的區(qū)碼和位碼.
4.區(qū)碼 漢字的第一個字節(jié)(因為漢字編碼是從0XA0區(qū)開始的,所以文件最前面就是從0XA0區(qū)開始, 要算出相對區(qū)碼)
位碼 漢字的第二個字節(jié)
這樣就可以得到漢字在HZK16中的絕對位置
offset=(94*(區(qū)碼-1)+(位碼-1))*32
注解
1.區(qū)碼減1是因為數(shù)組是以0為開始而區(qū)號是以1為開始的
2.(94*(區(qū)號-1)+(位碼-1))是一個漢字字模占用的字節(jié)數(shù)
3.最后乘以32 是因為漢字字庫文應(yīng)從 該位置起的32字節(jié)信息記錄該字的字模信息
圖片資源的存放
相比字符資源的存取,圖片就顯得輕松多了.
主要就一個方法的使用
public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)
把位圖的數(shù)據(jù)拷貝到pixels[]中,每一個都由一個表示顏色值的int值來表示
幅度參數(shù)表名調(diào)用者允許的像素組行間距
參數(shù)解釋
- pixels 接收位圖顏色值的數(shù)組
- offset 寫入到pixels[]中的第一個像素索引值
- stride pixels[]中的行間距個數(shù)值
- x 從位圖中讀取的第一個像素的x坐標值
- y 從位圖中讀取的第一個像素的y坐標值
- width 從每一行中讀取的像素寬度
- height 讀取的行數(shù)
int[] pixels = new int[bit.getWidth()*bit.getHeight()];//保存所有的像素的數(shù)組绒窑,圖片寬×高
bit.getPixels(pixels,0,bit.getWidth(),0,0,bit.getWidth(),bit.getHeight());
for(int i = 0; i < pixels.length; i++){
int clr = pixels[i];
int red = (clr & 0x00ff0000) >> 16; //取高兩位
int green = (clr & 0x0000ff00) >> 8; //取中兩位
int blue = clr & 0x000000ff; //取低兩位
System.out.println("r="+red+",g="+green+",b="+blue);
}
整理如下圖