來源 | HaaS技術社群
1、簡介
條形碼(barcode)是将寬度不等的多個黑條和空白,按照一定的編碼規則排列,用以表達一組資訊的圖形辨別符。常見的條形碼是由反射率相差很大的黑條(簡稱條)和白條(簡稱空)排成圖案。條形碼可以标出物品的生産國、制造廠家、商品名稱、生産日期、圖書分類号、郵件起止地點、類别、日期等許多資訊,因而在商品、圖書管理、郵政管理、銀行系統等許多領域都得到廣泛的應用,如今在我們的日常生活中也是随處可見。

2、條形碼發展史
随着社會文化以及生活形态的變化,美國的零售業從上世紀30年代從封閉式轉為開放式,随之而來的是結賬成為重大瓶頸,在1948年費城瓦斯科技學院一位名叫伯納德·塞爾沃的研究所學生無意中聽到當地一家連鎖超市的總裁懇請院長發明一種可以在收銀台處自動記錄商品銷售的方法,就開始嘗試着手研發條形碼,用以在收銀台處自動記錄商品。1969年起IBM也開始研究,并于4年後推出了一種既易于列印同時也能有效傳遞資訊的長方形條形碼。這種條形碼最終得到了當時的符号選擇委員會的認可,被命名為标準商品碼UPC(Uniform Product Code)。1974年在美國俄亥俄州特洛伊城的一個超市,賣出了世界上第一個印有條碼的商品——箭牌口香糖,這個商品目前還收藏在美國的國家博物館裡。在中國,1988年12月,經國務院準許成立了國家物品編碼協會。“八五”期間,國務院電子資訊系統推廣應用辦公室也将條碼技術作為重點推廣應用的10項工作之一。1992年我國第一家POS系統問世,标志着我國正式開始使用商品條碼。
3、條形碼碼制
一個完整的條形碼由兩側的靜區,起始字元,資料字元,校驗字元,終止字元組成:
靜區:位于條形碼兩側,無任何符号及資訊的白色區域,提示條碼閱讀器準備掃描。
起始字元:第一個字元,标志開始,閱讀器确認此字元存在後開始處理掃描脈沖。
資料字元:位于起始字元後面的字元,其結構異于起始字元,可允許雙向掃描,由0-9構成,這些數字有國碼,廠商号碼,商品代号,檢驗碼。
校驗字元:代表一種運算的結果,閱讀器在掃描的時候,對讀入的各字元進行運算,如果運算結果跟校驗字元相同,則代表本次掃描有效。
終止字元:最後一個字元,閱讀器确認此字元存在後結束掃描。
世界上常用的碼制比較多,常用的主要有以下幾種:
3.1、Code 128條形碼
Code 128條形碼為目前國内企業内部的自定義碼制,可以根據需要确定條形碼的長度和資訊,它編碼的資訊可以是數字,也可以包含字母,主要應用于工業生産線領域、圖書管理等,如表示産品序列号、圖書、文檔編号等。
有三種不同的版本:A(數字、大寫字母、控制字元)B(數字、大小字母、字元)C(雙位數字)
CODE128A:标準數字和大寫字母,控制符,特殊字元
CODE128B:标準數字和大寫字母,小寫字母,特殊字元
CODE128C:[00]-[99]的數字對集合,共100個
3.2、Code 39條形碼
Code 39條形碼是一種字元集為數字跟字元的條形碼,長度可變,不連續型,資訊量大,相對密度較低,印刷友善,主要用于制造業,圖書及票證自動化管理上。
3.3、Code 93碼
Code 93碼是一種類似于Code 39碼的條形碼,相比Code 39碼它的密度較高,同樣适用于工業制造領域 。
3.4、EAN條形碼
EAN條形碼是國際通用的符号體系,是一種長度固定、無含意的條形碼,所表達的資訊全部為數字,主要應用于商品辨別。
我國的EAN-13碼的編碼規則如下:
國家(地區)代碼 | 廠商代碼 | 商品代碼 | 校驗碼 |
13,12,11 | 10,9,8,7 | 6,5,4,3,2 | 1 |
EAN-8碼是EAN-13碼的縮短碼,由8位數字及條形碼組成,主要用于一些印刷面較小的零售商品上面。
8,7,6 | 5,4,3,2 |
3.5、UPC條形碼
UPC條形碼(統一産品代碼)隻能表示數字,有A、B、C、D、E五個版本,版本A-12位數字,版本E-7位數字,最後一位為校驗位,大小是寬1.5英寸(1英寸 - 2.54cm),高1英寸,而且背景要清晰,主要在美國和加拿大使用,用于工業、醫藥、倉儲等部門。
UPC條形碼的最後一位是校驗位。 掃描器通過校驗位判斷是否掃描了正确的号碼。 下面介紹如何用另外的11位數生成校驗位:
- 将所有奇數位置(第1、3、5、7、9和11位)上的數字相加。1+3+5+6+8+0=23
- 然後,将該數乘以3。23*3=69
- 将所有偶數位置(第2、4、6、8和10位)上的數字相加。2+4+6+7+9=28
- 然後,将該和與第2步所得的值相加。69+28=97
- 儲存第4步的值。要建立校驗位,需要确定一個值,當将該值與步驟4所得的值相加時,結果為10的倍數。97+3=100是以,校驗位為3。
3.6、25條形碼
25條形碼隻能表示數字0-9,長度可變,條形碼呈連續性,空不表示資訊,較多用于機場中。
交叉25條形碼(也叫穿插25碼):隻能表示數字0-9,長度可變,條形碼呈連續性,所有條與空都表示代碼,第一個數字由條開始,第二個數字由空組成,應用于商品批發、倉庫、機場、生産(包裝)識别、商業中,條形碼的識讀率高,可用于固定掃描器的可靠掃描,在所有一維條形碼中的密度最高。
3.7、庫德巴條形碼
庫德巴條形碼( Codabar)也稱“血庫用碼”,可表示數字0-9,字元$、+、-,還有隻能用作起始和終止符的a、b、c、d四個字元,空白區比窄條寬10倍,非連續性條形碼,每個字元表示為4條3空,條形碼長度可變,沒有校驗位,主要應用于血站的捐血員管理和血庫管理,也可作物料管理、圖書館、機場包裹發送中。
4、LittlevGL對條形碼的支援
在POS機等支付行業,條形碼是必須用到的,同樣圖形架構對條形碼的支援也是必須的,Code 128碼(包含了EAN128碼)可表示較全面的字元(數字、字母和符号),在同樣長度的條碼中可容納的字元長度較長(高密度),Code 128碼與Code 39碼有很多的相近性,都廣泛運用在企業内部管理、生産流程、物流控制系統方面。不同的在于Code 128比Code 39能表現更多的字元,機關長度裡的編碼密度更高。當機關長度裡不能容下Code 39編碼或編碼字元超出了Code 39的限制時,就可選擇Code 128來編碼。是以Code 128比Code 39更具靈活性。是以Code 128碼是企業内部管理系統最為廣泛使用的條碼碼制。
AliOS Things已經內建了LittleVGL了,是以這個輕量級GUI圖形架構的擴充主要考慮對Code 128碼的支援了。
如何支援條形碼
目前littlevgl并不支援Code 128碼,為此需要根據Code 128碼的生成規則,添加如下代碼,其中uint16_t width,跟uint16_t height代表生成的條形碼的寬跟高,char *bc_buf則是條形碼對應的字元串:
- lv_obj_t *barcode_create(lv_obj_t * par, uint16_t width, uint16_t height, const char *bc_buf)
- {
- lv_obj_t *obj = NULL;
- if(par == NULL || bc_buf == NULL || width == 0 || height == 0) {
- printf("barcode_create, param error!!\n");
- return NULL;
- }
- size_t size = code128_estimate_len(bc_buf);
- uint8_t *barcode_data = lv_mem_alloc(size);
- if(barcode_data == NULL) {
- printf("barcode_create, no memory 0!!\n");
- size = code128_encode_gs1(bc_buf, (char *)barcode_data, size);
- lv_color_t *orig_color_map = lv_mem_aligned_alloc(size*height*2, 32);
- if(orig_color_map == NULL) {
- printf("barcode_create, no memory 1!!\n");
- lv_mem_free(barcode_data);
- memset(orig_color_map, 0xff, size*height*2);
- int i = 0, j = 0;
- for(i=0; i
- if(barcode_data[i]) {
- for(j=0; j
- memset(&orig_color_map[j*size + i], 0x0, sizeof(lv_color_t));
- lv_color_t *dst_color_map = lv_mem_aligned_alloc(width*height*2, 32);
- if(dst_color_map == NULL) {
- printf("barcode_create, no memory 2!!\n");
- goto end;
- if(rgb565_scale(size, height, width, height, (uint8_t *)orig_color_map, (uint8_t *)dst_color_map) == 0) {
- lv_mem_aligned_free(dst_color_map);
- lv_img_dsc_t *img_des = lv_mem_alloc(sizeof(lv_img_dsc_t));
- if(img_des == NULL) {
- printf("barcode_create, no memory 3!!\n");
- memset(img_des, 0 , sizeof(lv_img_dsc_t));
- img_des->header.w = width;
- img_des->header.h = height;
- img_des->header.cf = LV_IMG_CF_TRUE_COLOR;
- img_des->data_size = width*height*2;
- img_des->data = (const uint8_t *)dst_color_map;
- obj = lv_img_create(par, NULL);
- lv_img_set_src(obj, img_des);
- if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(obj);
- /*The signal and design functions are not copied so set them here*/
- lv_obj_set_signal_func(obj, barcode_signal);
- end:
- lv_mem_aligned_free(orig_color_map);
- return obj;
code128_encode_gs1以及rgb565_scale會将字元串通過Code 128碼轉換成一個圖檔,并最終lv_img_create将這個圖檔顯示在螢幕上,如下圖:
開發者支援
如需更多技術支援,可加入釘釘開發者群,或者關注微信公衆号。
更多技術與解決方案介紹,請通路HaaS官方網站
https://haas.iot.aliyun.com。