1. 程式人生 > >使用HZK16字型檔檔案提取文字並顯示到OLED顯示屏上(Java Android實現)

使用HZK16字型檔檔案提取文字並顯示到OLED顯示屏上(Java Android實現)

最近在做要把文字(英文、漢字)顯示到OLED顯示屏上這方面內容,英文還好說,無非幾十個字元,網上一搜也都有現成的方法。但漢字可就比較棘手了,首先要實現漢字的顯示需要知道這個漢字的字模,這個我們可以很輕鬆地使用取字模軟體獲取(下邊有下載地址),這樣其實就可以了。棘手的是如果我要取得任意漢字的字模呢?不可能把所有字模的資訊都生成吧!但是如果用到哪個生成哪個很明顯擴充套件性不高也非常麻煩。這時我們就想到了使用字型檔,在字型檔中取出漢字的字模。於是問題來了,調取字型檔大多使用的是c語言,讓我大Android(Java)情何以堪,不過字型檔畢竟是一個檔案嘛,你在c語言能開啟查詢,我在java裡自然也能開啟查詢嘍。於是各種搜尋資料,各種鬱悶最終是成功了!中間遇到許多許多問題。趁現在思路比較清晰寫下來,一是備忘,二也是說不定能幫到一樣有這種問題困擾的各位。

首先OLED顯示這塊可以參考:

或自行搜尋。我們使用的是16x96 漢字為16x16共陰極列行式逆向輸出(輸出方式很重要!)

HZK16(16x16漢字型檔)

(後邊會附上字型檔下載地址,包含多種字型和大小的字型檔)

相關知識可參考下邊連線或自行搜尋

第一步就是通過字型檔(通過漢字的區碼和位碼得到偏移量)取出字模資訊:

String s = "我的測試";

        /*
        * 迴圈取得每個漢字
        * */
        for (int i = 0; i < s.length(); i++) {

            //獲取漢字的資訊
            getHex(getByte(i, s));
        }

首先獲取漢字的位元組資訊:
 public byte[] getByte(int i, String s) {
        byte[] b_gbk = new byte[1];
        String ss = s.substring(i, i + 1);
        Log.i("hzkTest--->>>", ss);
        try {
            b_gbk = ss.getBytes("GBK");//必須轉為GBK編碼
            Log.i("hzkTest--->>>", "Length=" + b_gbk.length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return b_gbk;
    }

需要注意的是需要轉為GBK編碼,否則預設的unicode編碼一個漢字所佔的位元組為3,會造成後邊計算區碼位碼偏移量錯誤!

其次,根據位元組資訊獲取區位碼和偏移量:

private void getHex(byte[] data) {
        int size = 16;//字模的size
        int sum = (size * size / 8);
        byte iHigh, iLow;
        iHigh = data[1];
        iLow = data[0];
        Log.i("hzkTest--->>>", "h=" + iHigh + ",l=" + iLow);
        int IOffset;//偏移量
        IOffset = (94 * (iLow + 256 - 161) + (iHigh + 256 - 161)) * sum;//+256防止byte值為負   漢字字模在字型檔中的偏移地址
        Log.i("hzkTest--->>>", "IOffset=" + IOffset);

        InputStream is = getResources().openRawResource(R.raw.hzk16);

        try {
            is.read(new byte[IOffset]);
            byte iBuff[] = new byte[size * 2];//連續讀入
            is.read(iBuff);

            getBinary(iBuff);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
其中raw為安卓res資料夾下的raw資原始檔夾,把hzk16檔案放到該資料夾下。

第三就是通過偏移量獲取漢字的二進位制資料:

 /*
    * 獲取漢字的二進位制資料
    * */
    private void getBinary(byte[] iBuff) {
        StringBuffer stringBuffer=new StringBuffer();
        int i, j, k;
        for (i = 0; i < 16; i++) {
            for (j = 0; j < 2; j++)
                for (k = 0; k < 8; k++) {
                    if ((iBuff[i * 2 + j] & (0x80 >> k)) >= 1) {
                        stringBuffer.append("1");
                    } else {
                        stringBuffer.append("0");
                    }
                }
        }
        Log.i("hzkTest--->>>", stringBuffer.toString());

        //把 0 1 按照共陰極逆向式列行式取碼方式輸出
        getRowLineReverseCode(stringBuffer);
    }

第四非常關鍵,就是要根據OLED的取字方式來重新排列我們獲得的0 1 資料,比如我們的就是共陰極列行式逆向輸出。

關於取模方式可自己搜尋,還有下邊給出的取模軟體有取模方式的演示,可以參考。不過個人認為他的那個演示逆向、順向貌似反了!

   /*
    * 按照共陰極逆向式列行式取碼方式(OLED顯示方式)重新輸出排列 0 1
    * */
    private void getRowLineReverseCode(StringBuffer sb) {
        //得到前8行16列 128個
        String pre128 = sb.substring(0, 128);
        Log.i("hzkTest--->>>", "pre128--->>" + pre128);
        //取出每16列的8個數據
        for (int i = 0; i < 16; i++) {
            StringBuffer sb1 = new StringBuffer();
            for (int j = 112; j >=0; ) {
                String s = pre128.substring(i + j, i + j + 1);
                sb1.append(s);
                j -= 16;
            }
            Log.i("hzkTest--->>>", "pre128--->>列行式2進位制-->>" + sb1 + ",");
            Log.i("hzkTest--->>>", "pre128--->>列行式10進位制-->>" + Integer.parseInt(sb1.toString(),2) + ",");
            Log.i("hzkTest--->>>", "pre128--->>列行式16進位制-->>" + binaryString2hexString(sb1.toString()) + ",");
            //直接使用十進位制資料,不再轉換16進位制
            buffer10.append(Integer.parseInt(sb1.toString(),2) + ",");
//            hexBuffer.append(binaryString2hexString(sb1.toString())+",");
        }

        //得到後8行16列 128個
        String las128 = sb.substring(128, 256);
        Log.i("hzkTest--->>>", "las128--->>" + las128);
        //取出每16列的8個數據
        for (int i = 0; i < 16; i++) {
            StringBuffer sb2 = new StringBuffer();
            for (int j = 112; j >=0; ) {
                String s = las128.substring(i + j, i + j + 1);
                sb2.append(s);
                j -= 16;
            }
            Log.i("hzkTest--->>>", "las128--->>列行式2進位制-->>" + sb2 + ",");
            Log.i("hzkTest--->>>", "las128--->>列行式16進位制-->>" + binaryString2hexString(sb2.toString()) + ",");
            //直接使用十進位制資料,不再轉換16進位制
            buffer10.append(Integer.parseInt(sb2.toString(),2) + ",");
//            hexBuffer.append(binaryString2hexString(sb2.toString())+",");
        }

//        Log.i("hzkTest--->>>","HEX--->>>>"+hexBuffer);
        Log.i("hzkTest--->>>","10---->>>>"+buffer10);
    }

之前有先轉為16進位制,不過後來發現直接使用10進位制就行。所以沒必要轉來轉去了。

按照我們要求取出來的資料得到後就基本大功告成了。即文中的buffer10(意思是10進位制的字串),把這個字串按”,“號擷取再強轉為int就是我們OLED顯示屏需要的資料了。

這樣我們就可以實現輸入任意的漢字了!

用兩張圖簡單說明:

這是從字型檔中取出的【我】的0 1 資料



感覺非常複雜自己也折騰了好久,但是感覺也沒寫出來什麼東西!什麼鬼!驚恐驚恐

如果有錯誤的地方,歡迎批評指正!謝謝!


附:

漢字取字模軟體下載:

漢字字型檔下載地址:

相關推薦

使用HZK16字型檔檔案提取文字顯示OLED顯示屏Java Android實現

最近在做要把文字(英文、漢字)顯示到OLED顯示屏上這方面內容,英文還好說,無非幾十個字元,網上一搜也都有現成的方法。但漢字可就比較棘手了,首先要實現漢字的顯示需要知道這個漢字的字模,這個我們可以很輕鬆地使用取字模軟體獲取(下邊有下載地址),這樣其實就可以了。棘手的是如果我

替換檔案中某個字串寫入新內容Java程式碼實現

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileWri

讀取文字檔案顯示在螢幕

#include<stdio.h> #include<string.h> void main() { FILE *fp; //建立一個檔案指標*fp char ch; f

CSS多行文字顯示省略號

  比如說有一個需求:最多隻能顯示兩行文字,超過一行則換行,超過兩行則顯示省略號 more-wrap($n) display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: $n; overflow: hid

從Tensorflow模型檔案中解析顯示網路結構圖CKPT模型篇

上一篇文章《從Tensorflow模型檔案中解析並顯示網路結構圖(pb模型篇)》中介紹瞭如何從pb模型檔案中提取網路結構圖並實現視覺化,本文介紹如何從CKPT模型檔案中提取網路結構圖並實現視覺化。理論上

將A檔案中與B檔案同名但不同字尾名的檔案提取出來扔到C資料夾中 matlab

fileList = dir('C:\Users\DELL\Desktop\data\helen\train\train_res\*.jpg'); sourcePath = 'C:\Users\DELL\Desktop\helen\helen\trainset\'; targetPath = '

例7.12 將 a 至 z的26個英文字母寫入檔案,而後從該檔案中讀取顯示出來。

//例7.12 將 “a"至”z"的26個英文字母寫入檔案,而後從該檔案中讀取並顯示出來。 #include<iostream> #include<fstream> using namespace std; int test_write(){

java 從hadoop hdfs讀取檔案 進行groupby顯示為條形圖

題意:從檔案、網路或者資料庫中讀取資料(格式自定、資料自定),顯示統計結果(包括圖形兩種以上),使用者介面自定 1 讀取資料 1.1 準備資料 此資料為TPCH基準測試集中lineitem.tdl檔案中前25行 示例:第一行如下 1|1

Unity載入網路圖片顯示在UGUI,解決載入網路圖片出現問號的問題及其案例分析,例項Demo親測可用

Unity載入網路圖片並顯示在UGUI上,解決載入網路圖片出現問號的問題及其案例分析,例項Demo親測可用 最近自己在載入網路圖片的時候也遇到了載入的圖片無法顯示或者是問號的問題。下面就分析下為什麼會出現這樣的情況。   首先我們直接上程式碼(比較簡單) using U

點選下拉框切換頁面顯示在當前頁語言切換

預設html: <div class="styled-select">                       

將COCO2017標註檔案中的bbox顯示在圖片

  from pycocotools.coco import COCO import cv2 import pandas as pd def showNimages(imageidFile, annFile, imageFile, resultFile): """

openlayers讀取KML顯示在地圖

在ol裡面讀取KML檔案時,如果style總是不對,需要設定一個重要的屬性 extractStyles: false  不多說了,上程式碼示例 var projection = ol.proj.get('EPSG:3857'); var map = ne

css 如何讓文字標題顯示在邊框

方法一、 <style> .box{ position:relative; border:1px solid red; } .box::before{ content:attr(title);

CSS 單行溢位文字顯示省略號...的方法相容IE FF

學習篇: 今天有朋友在52css.com的留言板提出一個問題:為什麼 text-overflow:ellipsis的時候沒有任何效果呀?text-overflow是一個比較特殊的屬性,在CSS手冊中,這個屬性是這樣定義的:   語法:    text-overflo

通過js得到時間,顯示到jsp

$(document).ready(function(){load();aaa();   }); function load(){var curr_time = new Date();var today;var yesterday;var y = curr_time.getFullYear();   var

獲取網路的圖片,顯示在介面的簡單實現

佈局檔案如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" androi

android 文字疊加顯示在圖片之上控制元件的實現 -- 充分利用TextView

如果您認為本部落格不錯,讀後覺得有收穫,不妨打賞讚助我一下,讓我有動力繼續寫出高質量的部落格。 贈人玫瑰,手有餘香。分享技術,傳遞快樂。 有心課堂,傳遞的不僅僅是技術! QQ交流群:250468947 有心課堂會員,請加入VIP QQ交流

使用百度地圖SDK定位當前位置顯示在地圖

package com.shz.baidumap; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import andr

BZOJ 3674 可持久化查集加強版主席樹變形

als ret desc scan sync scanf ops 只需要 ica 3673: 可持久化並查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [

顯示頁面鏈接7.5.1

info item mat pub 以及 size action get 傳遞 1、添加視圖模型 PagingInfo(WebUI.Models)(這一步不用改,每個項目照用就行)     創建 PagingInfo 視圖模型,將“可用頁面數”、&