android编程实现128条形码的生成和识别

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/blogercn/article/details/74990304

条形码二维码由于规则简单,读取效率,在目前人们生活中应用广泛。一般情况下,不必了解原理,就可以借助ZXING和BARCODE,ZBAR等各种开发库实现。在某些特殊场合或者特别要求的场合下,比如发明一种特殊的条形码,比如改进编码规则,比如对特别识别过程优化等情况。CODE128应用十分广泛,这里从CODE128的编码规则并从规则出发开发相应的二维码生成和识别程序来抛砖引玉。

 

CODE128简介

CODE128 码于 1981 年推出,是一种长度可变、连续性的字母数字条码。与其他一维条码比 较起来,相对较为复杂,支持的宇元也相对较多,又有不同的编码为式可供交互运用,因此其应 用弹性也较大。
CODE 128 特性

1、具有 A、 B、 C 三种不同的编码类型,可提供标准 ASC II中 128 个宇元的编码使用; 2、允许双向扫描;

3、可自行决定是否加上校验位;

4、条码长度可调,但包括开始位和结束位在内,不可超过 232 个字元;

5、同一个 CODE128 码可以由 A、 B、 C 三种不同编码规则互换,既可扩大字元选择的范围, 也可缩短编码的长度。
CODE 128 编码方式的编码范围

1、 CODE128A:标准数字、大写字母、控制符及特殊宇符;

2、 CODE128B:标准数字、大写宇母、小写字母及特殊字符;

3、 CODE128C/EAN128: [ 00]~[ 99]的数字对集合,共 100 个,既只能表示偶数位长 度的数字。
CODE 128 编码规则

开始位+[ FNC1(为 EAN128 码时附加)]+数据位+校验位+结束位

 

CODE128 校验位计算

(开始位对应 ID+每位数据在整个数据中的位置×每位数据对应的 ID 值) % 103
CODE 128 编码表如下,

横向依次对应索引ID, ABC三种编码字符,BANDCODE和二进制编码表,纵向对支持的字符,C码只支持数字,B码支持数字,字母和特殊字符,A码支持数字,字母,特殊字符和控制字符

 

   A  B  C   A B C
00  SP  SP   00  11011001100   
01  !  !   01  11001101100   
02  "  "   02  11001100110   
03  #  #   03  10010011000   
04  $  $   04  10010001100   
05  %  %   05  10001001100   
06  &  &   06  10011001000   
07  /'  /'   07  10011000100   
08  (  (   08  10001100100   
09  )  )   09  11001001000   
10  *  *   10  11001000100   
11  +  +   11  11000100100   
12  ,  ,   12  10110011100   
13  -  -   13  10011011100   
14  .  .   14  10011001110   
15  /  /   15  10111001100   
16  0  0   16  10011101100   
17  1 1   17  10011100110   
18  2 2   18  11001110010   
19  3  3   19  11001011100   
20  4  4   20  11001001110   
21  5 5   21  11011100100   
22  6 6   22  11001110100   
23  7  7   23  11101101110   
24  8 8   24  11101001100   
25  9  9   25  11100101100   
26  :  :   26  11100100110   
27  ;  ;   27  11101100100   
28  <  <   28  11100110100   
29  =  =   29  11100110010   
30  >  >   30  11011011000   
31  ?  ?   31  11011000110   
32  @  @   32  11000110110   
33  A  A   33  10100011000   
34  B  B   34  10001011000   
35  C  C   35  10001000110   
36  D  D   36  10110001000   
37  E  E   37  10001101000   
38  F  F   38  10001100010   
39  G  G   39  11010001000   
40  H  H   40  11000101000   
41  I  I   41  11000100010   
42  J  J   42  10110111000   
43  K  K   43  10110001110   
44  L  L   44  10001101110   
45  M  M   45  10111011000   
46  N  N   46  10111000110   
47  O  O   47  10001110110   
48  P  P   48  11101110110   
49  Q  Q   49  11010001110   
50  R  R   50  11000101110   
51  S  S   51  11011101000   
52  T  T   52  11011100010    
53  U  U   53  11011101110
54  V  V   54  11101011000
55  W  W   55  11101000110
56  X  X   56  11100010110
57  Y  Y   57  11101101000
58  Z  Z   58  11101100010
59  [  [   59  11100011010
60  //  //   60  11101111010
61  ]  ]   61  11001000010
62  ^  ^   62  11110001010
63  _  _   63  10100110000
64  NUL  `   64  10100001100
65  SOH  a   65  10010110000
66  STX  b   66  10010000110
67  ETX  c   67  10000101100
68  EOT  d   68  10000100110
69  ENQ  e   69  10110010000
70  ACK  f   70  10110000100
71  BEL  g   71  10011010000
72  BS  h   72  10011000010
73  HT  I   73  10000110100
74  LF  j   74  10000110010
75  VT  k   75  11000010010
76  FF  l   76  11001010000
76  FF  l   76  11001010000
77  CR  m   77  11110111010
78  SO  n   78  11000010100
79  SI  o   79  10001111010
80  DLE  p   80  10100111100
81  DC1  q   81  10010111100
82  DC2  r   82  10010011110
83  DC3  s   83  10111100100
84  DC4  t   84  10011110100
85  NAK  u   85  10011110010
86  SYN  v   86  11110100100
87  ETB  w   87  11110010100
88  CAN  x   88  11110010010
89  EM  y   89  11011011110
90  SUB  z   90  11011110110
91  ESC  {   91  11110110110
92  FS  |   92  10101111000
93  GS  }   93  10100011110
94  RS  ~   94  10001011110
95  US  DEL   95  10111101000
96  FNC3  FNC3   96  10111100010
97  FNC2  FNC2   97  11110101000
98  SHIFT  SHIFT   98  11110100010
99  CodeC  CodeC   99  10111011110
100  CodeB  FNC4   CodeB  10111101110
101  FNC4  CodeA   CodeA  11101011110
102  FNC1  FNC1   FNC1  11110101110
103  STARTA  STARTA   STARTA  11010000100
104  STARTB  STARTB   STARTB  11010010000
105  STARTC  STARTC   STARTC  11010011100
终止符 STOP  STOP   STOP  1100011101011


编程实现,创建一个二维数组表,把编码表存入,数组第0列A码,第1列B码,第2列C码,第3列bandcode,第4列对就二进制编码值,整体算法十分简单,把要编码的内容读入,按照下表转为二进制编码值,生成数据位,最后按照规则,开始位+[FNC1(为 EAN128 码时附加)]+数据位+校验位+结束位组合成完整二进制编码数据,最后调用平台GUI函数按照合成的完整二进制码,1对应白色竖线,0对应黑色竖线绘制出来,线高和线宽可以根据需要调整,下面给出完整的JAVA代码和android代码,java绘图使用AWT图形库。

public class TestCode128C {
	String[][] code128 = { { " ", " ", "00", "212222", "11011001100" },
			{ "!", "!", "01", "222122", "11001101100" },
			{ "\"", "\"", "02", "222221", "11001100110" },
			{ "#", "#", "03", "121223", "10010011000" },
			{ "$", "$", "04", "121322", "10010001100" },
			{ "%", "%", "05", "131222", "10001001100" },
			{ "&", "&", "06", "122213", "10011001000" },
			{ "'", "'", "07", "122312", "10011000100", },
			{ "(", "(", "08", "132212", "10001100100" },
			{ ")", ")", "09", "221213", "11001001000" },
			{ "*", "*", "10", "221312", "11001000100" },
			{ "+", "+", "11", "231212", "11000100100" },
			{ ",", ",", "12", "112232", "10110011100" },
			{ "-", "-", "13", "122132", "10011011100" },
			{ ".", ".", "14", "122231", "10011001110" },
			{ "/", "/", "15", "113222", "10111001100" },
			{ "0", "0", "16", "123122", "10011101100" },
			{ "1", "1", "17", "123221", "10011100110" },
			{ "2", "2", "18", "223211", "11001110010", },
			{ "3", "3", "19", "221132", "11001011100" },
			{ "4", "4", "20", "221231", "11001001110", },
			{ "5", "5", "21", "213212", "11011100100" },
			{ "6", "6", "22", "223112", "11001110100" },
			{ "7", "7", "23", "312131", "11101101110" },
			{ "8", "8", "24", "311222", "11101001100" },
			{ "9", "9", "25", "321122", "11100101100" },
			{ ":", ":", "26", "321221", "11100100110" },
			{ ";", ";", "27", "312212", "11101100100" },
			{ "<", "<", "28", "322112", "11100110100" },
			{ "=", "=", "29", "322211", "11100110010" },
			{ ">", ">", "30", "212123", "11011011000" },
			{ "?", "?", "31", "212321", "11011000110" },
			{ "@", "@", "32", "232121", "11000110110" },
			{ "A", "A", "33", "111323", "10100011000" },
			{ "B", "B", "34", "131123", "10001011000" },
			{ "C", "C", "35", "131321", "10001000110" },
			{ "D", "D", "36", "112313", "10110001000" },
			{ "E", "E", "37", "132113", "10001101000" },
			{ "F", "F", "38", "132311", "10001100010" },
			{ "G", "G", "39", "211313", "11010001000" },
			{ "H", "H", "40", "231113", "11000101000" },
			{ "I", "I", "41", "231311", "11000100010" },
			{ "J", "J", "42", "112133", "10110111000" },
			{ "K", "K", "43", "112331", "10110001110" },
			{ "L", "L", "44", "132131", "10001101110" },
			{ "M", "M", "45", "113123", "10111011000" },
			{ "N", "N", "46", "113321", "10111000110" },
			{ "O", "O", "47", "133121", "10001110110" },
			{ "P", "P", "48", "313121", "11101110110" },
			{ "Q", "Q", "49", "211331", "11010001110" },
			{ "R", "R", "50", "231131", "11000101110" },
			{ "S", "S", "51", "213113", "11011101000" },
			{ "T", "T", "52", "213311", "11011100010" },
			{ "U", "U", "53", "213131", "11011101110" },
			{ "V", "V", "54", "311123", "11101011000" },
			{ "W", "W", "55", "311321", "11101000110" },
			{ "X", "X", "56", "331121", "11100010110" },
			{ "Y", "Y", "57", "312113", "11101101000" },
			{ "Z", "Z", "58", "312311", "11101100010" },
			{ "[", "[", "59", "332111", "11100011010" },
			{ "\\", "\\", "60", "314111", "11101111010" },
			{ "]", "]", "61", "221411", "11001000010" },
			{ "^", "^", "62", "431111", "11110001010" },
			{ "_", "_", "63", "111224", "10100110000" },
			{ "NUL", "`", "64", "111422", "10100001100" },
			{ "SOH", "a", "65", "121124", "10010110000" },
			{ "STX", "b", "66", "121421", "10010000110" },
			{ "ETX", "c", "67", "141122", "10000101100" },
			{ "EOT", "d", "68", "141221", "10000100110" },
			{ "ENQ", "e", "69", "112214", "10110010000" },
			{ "ACK", "f", "70", "112412", "10110000100" },
			{ "BEL", "g", "71", "122114", "10011010000" },
			{ "BS", "h", "72", "122411", "10011000010" },
			{ "HT", "i", "73", "142112", "10000110100" },
			{ "LF", "j", "74", "142211", "10000110010" },
			{ "VT", "k", "75", "241211", "11000010010" },
			{ "FF", "I", "76", "221114", "11001010000" },
			{ "CR", "m", "77", "413111", "11110111010" },
			{ "SO", "n", "78", "241112", "11000010100" },
			{ "SI", "o", "79", "134111", "10001111010" },
			{ "DLE", "p", "80", "111242", "10100111100" },
			{ "DC1", "q", "81", "121142", "10010111100" },
			{ "DC2", "r", "82", "121241", "10010011110" },
			{ "DC3", "s", "83", "114212", "10111100100" },
			{ "DC4", "t", "84", "124112", "10011110100" },
			{ "NAK", "u", "85", "124211", "10011110010" },
			{ "SYN", "v", "86", "411212", "11110100100" },
			{ "ETB", "w", "87", "421112", "11110010100" },
			{ "CAN", "x", "88", "421211", "11110010010" },
			{ "EM", "y", "89", "212141", "11011011110" },
			{ "SUB", "z", "90", "214121", "11011110110" },
			{ "ESC", "{", "91", "412121", "11110110110" },
			{ "FS", "|", "92", "111143", "10101111000" },
			{ "GS", "},", "93", "111341", "10100011110" },
			{ "RS", "~", "94", "131141", "10001011110" },
			{ "US", "DEL", "95", "114113", "10111101000" },
			{ "FNC3", "FNC3", "96", "114311", "10111100010" },
			{ "FNC2", "FNC2", "97", "411113", "11110101000" },
			{ "SHIFT", "SHIFT", "98", "411311", "11110100010" },
			{ "CODEC", "CODEC", "99", "113141", "10111011110" },
			{ "CODEB", "FNC4", "CODEB", "114131", "10111101110" },
			{ "FNC4", "CODEA", "CODEA", "311141", "11101011110" },
			{ "FNC1", "FNC1", "FNC1", "411131", "11110101110" },
			{ "StartA", "StartA", "StartA", "211412", "11010000100" },
			{ "StartB", "StartB", "StartB", "211214", "11010010000" },
			{ "StartC", "StartC", "StartC", "211232", "11010011100" },
			{ "Stop", "Stop", "Stop", "2331112", "1100011101011" }, };

	/**
	 * 生产Code128的条形码的code
	 * 
	 * @param barCode
	 * @param encode
	 * @return
	 */
	public String getCode(String barCode, String encode) {
		String _Text = "";// 返回的参数
		List<Integer> _TextNumb = new ArrayList<Integer>();// 2截取位的组合
		int _Examine = 105; // 首位
		// 编码不能是奇数
		if (!((barCode.length() & 1) == 0))
			return "";
		while (barCode.length() != 0) {
			int _Temp = 0;
			try {
				// Code128 编码必须为数字
				_Temp = Integer.valueOf(barCode.substring(0, 2));
			} catch (Exception e) {
				e.printStackTrace();
				return "";
			}
			// 获得条纹
			_Text += getValue(barCode, barCode.substring(0, 2), _Temp);
			_TextNumb.add(_Temp);
			// 条码截取2个就需要去掉用过的前二位
			barCode = barCode.substring(2);
		}
		if (_TextNumb.size() == 0) {
			return "";
		}
		_Text = getValue(_Examine) + _Text; // 获取开始位
		for (int i = 0; i != _TextNumb.size(); i++) {
			_Examine += _TextNumb.get(i) * (i + 1);
		}
		_Examine = _Examine % 103; // 获得校验位
		_Text += getValue(_Examine); // 获取校验位
		_Text += "1100011101011"; // 结束位
		return _Text;
	}

	/**
	 * 根据编号获得条纹
	 * 
	 * @param encode
	 * @param p_Value
	 * @param p_SetID
	 * @return
	 */
	private String getValue(String encode, String p_Value, int p_SetID) {
		return code128[p_SetID][4];
	}

	// / <summary>
	// / 根据编号获得条纹
	// / </summary>
	// / <param name="p_CodeId"></param>
	// / <returns></returns>
	private String getValue(int p_CodeId) {
		return code128[p_CodeId][4];
	}

	private int m_nImageHeight = 40; // 条码的高度像素数

	public static void main(String[] args) throws Exception {

		TestCode128C c = new TestCode128C();
		String barCode = c.getCode("118842807789", "");
		c.kiCode128C(barCode, 500, "D:/code128C.jpg");

	}

	// / <summary>
	// / 生成条码
	// / </summary>
	// / <param name="BarString">条码模式字符串</param>
	// / <param name="Height">生成的条码高度</param>
	// / <returns>条码图形</returns>
	public void kiCode128C(String barString, int Height, String path) {
		try {
			//File myPNG = new File(path);
			m_nImageHeight = Height;
			OutputStream out = new FileOutputStream(path);
			if (null == barString || null == out || 0 == barString.length())
				return;
			int nImageWidth = 0;
			char[] cs = barString.toCharArray();
			for (int i = 0; i != cs.length; i++) { 
				nImageWidth = cs.length*10;
			}

			BufferedImage bi = new BufferedImage(nImageWidth, m_nImageHeight,
					BufferedImage.TYPE_INT_RGB);
			Graphics g = bi.getGraphics();

			for (int i = 0; i < cs.length; i++) {
				if ("1".equals(cs[i] + "")) {
					g.setColor(Color.BLACK);
					g.fillRect(i*10, 0, 10, m_nImageHeight);
				} else {
					g.setColor(Color.WHITE);
					g.fillRect(i*10, 0, 10, m_nImageHeight);
				}
			}
			//JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			//encoder.encode(bi);
			
			ImageIO.write(bi, "jpg", out);
			out.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

在android上绘出条形码供机器自动化使用


public class MyView extends View {


    public MyView(Context context) {
        super(context);

    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public MyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        String barCode = Code128C.getCode("118842807789", "");
        int m_nImageHeight = 100;
        char[] cs = barCode.toCharArray();
        Paint p = new Paint();
            for (int i = 0; i < cs.length; i++) {
                if ("1".equals(cs[i] + "")) {
                    //g.setColor(Color.BLACK);
                    //g.fillRect(i, 0, 1, m_nImageHeight);
                    p.setColor(Color.BLACK);
                    //canvas.drawRect(i*10, 0, i*10+10, m_nImageHeight, p);
                } else {
                    //g.setColor(Color.WHITE);
                    //g.fillRect(i, 0, 1, m_nImageHeight);
                    p.setColor(Color.WHITE);
                    //canvas.drawRect(i*10, 0, i*10+10, m_nImageHeight, p);
                }
                canvas.drawRect(i*10, 0, i*10+10, m_nImageHeight, p);
            }
    }
}



展开阅读全文

没有更多推荐了,返回首页