微信小程序带参数生成条形码

2018-05-29  本文已影响0人  zx一个胖子

首先在utils文件下创建barcode.js与index.js两个文件

1.在barcode.js中复制如下代码(此代码已经改动过,测试可用):

var CHAR_TILDE = 126;

var CODE_FNC1 = 102;

var SET_STARTA = 103;

var SET_STARTB = 104;

var SET_STARTC = 105;

var SET_SHIFT = 98;

var SET_CODEA = 101;

var SET_CODEB = 100;

var SET_STOP = 106;

var REPLACE_CODES = {

  CHAR_TILDE: CODE_FNC1 //~ corresponds to FNC1 in GS1-128 standard

}

var CODESET = {

  ANY: 1,

  AB: 2,

  A: 3,

  B: 4,

  C: 5

};

function getBytes(str) {

  var bytes = [];

  for (var i = 0; i < str.length; i++) {

    bytes.push(str.charCodeAt(i));

  }

  return bytes;

}

exports.code128 = function (ctx, text, width, height) {

  width = parseInt(width);

  height = parseInt(height);

  var codes = stringToCode128(text);

  var g = new Graphics(ctx, width, height);

  var barWeight = g.area.width / ((codes.length - 3) * 11 + 35);

  var x = g.area.left;

  var y = g.area.top;

  for (var i = 0; i < codes.length; i++) {

    var c = codes[i];

    //two bars at a time: 1 black and 1 white

    for (var bar = 0; bar < 8; bar += 2) {

      var barW = PATTERNS[c][bar] * barWeight;

      // var barH = height - y - this.border;

      var barH = height - y;

      var spcW = PATTERNS[c][bar + 1] * barWeight;

      //no need to draw if 0 width

      if (barW > 0) {

        g.fillFgRect(x, y, barW, barH);

      }

      x += barW + spcW;

    }

  }

  ctx.draw();

}

function stringToCode128(text) {

  var barc = {

    currcs: CODESET.C

  };

  var bytes = getBytes(text);

  //decide starting codeset

  var index = bytes[0] == CHAR_TILDE ? 1 : 0;

  var csa1 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;

  var csa2 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;

  barc.currcs = getBestStartSet(csa1, csa2);

  barc.currcs = perhapsCodeC(bytes, barc.currcs);

  //if no codeset changes this will end up with bytes.length+3

  //start, checksum and stop

  var codes = new Array();

  switch (barc.currcs) {

    case CODESET.A:

      codes.push(SET_STARTA);

      break;

    case CODESET.B:

      codes.push(SET_STARTB);

      break;

    default:

      codes.push(SET_STARTC);

      break;

  }

  for (var i = 0; i < bytes.length; i++) {

    var b1 = bytes[i]; //get the first of a pair

    //should we translate/replace

    if (b1 in REPLACE_CODES) {

      codes.push(REPLACE_CODES[b1]);

      i++ //jump to next

      b1 = bytes[i];

    }

    //get the next in the pair if possible

    var b2 = bytes.length > (i + 1) ? bytes[i + 1] : -1;

    codes = codes.concat(codesForChar(b1, b2, barc.currcs));

    //code C takes 2 chars each time

    if (barc.currcs == CODESET.C) i++;

  }

  //calculate checksum according to Code 128 standards

  var checksum = codes[0];

  for (var weight = 1; weight < codes.length; weight++) {

    checksum += (weight * codes[weight]);

  }

  codes.push(checksum % 103);

  codes.push(SET_STOP);

  //encoding should now be complete

  return codes;

  function getBestStartSet(csa1, csa2) {

    //tries to figure out the best codeset

    //to start with to get the most compact code

    var vote = 0;

    vote += csa1 == CODESET.A ? 1 : 0;

    vote += csa1 == CODESET.B ? -1 : 0;

    vote += csa2 == CODESET.A ? 1 : 0;

    vote += csa2 == CODESET.B ? -1 : 0;

    //tie goes to B due to my own predudices

    return vote > 0 ? CODESET.A : CODESET.B;

  }

  function perhapsCodeC(bytes, codeset) {

    for (var i = 0; i < bytes.length; i++) {

      var b = bytes[i]

      if ((b < 48 || b > 57) && b != CHAR_TILDE)

        return codeset;

    }

    if (bytes.length % 2 == 0) {

      return CODESET.C

    }else{

      return CODESET.A;

    }

  }

  //chr1 is current byte

  //chr2 is the next byte to process. looks ahead.

  function codesForChar(chr1, chr2, currcs) {

    var result = [];

    var shifter = -1;

    if (charCompatible(chr1, currcs)) {

      if (currcs == CODESET.C) {

        if (chr2 == -1) {

          shifter = SET_CODEB;

          currcs = CODESET.B;

        }

        else if ((chr2 != -1) && !charCompatible(chr2, currcs)) {

          //need to check ahead as well

          if (charCompatible(chr2, CODESET.A)) {

            shifter = SET_CODEA;

            currcs = CODESET.A;

          }

          else {

            shifter = SET_CODEB;

            currcs = CODESET.B;

          }

        }

      }

    }

    else {

      //if there is a next char AND that next char is also not compatible

      if ((chr2 != -1) && !charCompatible(chr2, currcs)) {

        //need to switch code sets

        switch (currcs) {

          case CODESET.A:

            shifter = SET_CODEB;

            currcs = CODESET.B;

            break;

          case CODESET.B:

            shifter = SET_CODEA;

            currcs = CODESET.A;

            break;

        }

      }

      else {

        //no need to shift code sets, a temporary SHIFT will suffice

        shifter = SET_SHIFT;

      }

    }

    //ok some type of shift is nessecary

    if (shifter != -1) {

      result.push(shifter);

      result.push(codeValue(chr1));

    }

    else {

      if (currcs == CODESET.C) {

        //include next as well

        result.push(codeValue(chr1, chr2));

      }

      else {

        result.push(codeValue(chr1));

      }

    }

    barc.currcs = currcs;

    return result;

  }

}

//reduce the ascii code to fit into the Code128 char table

function codeValue(chr1, chr2) {

  if (typeof chr2 == "undefined") {

    return chr1 >= 32 ? chr1 - 32 : chr1 + 64;

  }

  else {

    return parseInt(String.fromCharCode(chr1) + String.fromCharCode(chr2));

  }

}

function charCompatible(chr, codeset) {

  var csa = codeSetAllowedFor(chr);

  if (csa == CODESET.ANY) return true;

  //if we need to change from current

  if (csa == CODESET.AB) return true;

  if (csa == CODESET.A && codeset == CODESET.A) return true;

  if (csa == CODESET.B && codeset == CODESET.B) return true;

  return false;

}

function codeSetAllowedFor(chr) {

  if (chr >= 48 && chr <= 57) {

    //0-9

    return CODESET.ANY;

  }

  else if (chr >= 32 && chr <= 95) {

    //0-9 A-Z

    return CODESET.AB;

  }

  else {

    //if non printable

    return chr < 32 ? CODESET.A : CODESET.B;

  }

}

var Graphics = function (ctx, width, height) {

  this.width = width;

  this.height = height;

  this.quiet = Math.round(this.width / 40);

  this.border_size = 0;

  this.padding_width = 0;

  this.area = {

    width: width - this.padding_width * 2 - this.quiet * 2,

    height: height - this.border_size * 2,

    top: this.border_size - 4,

    left: this.padding_width + this.quiet

  };

  this.ctx = ctx;

  this.fg = "#000000";

  this.bg = "#ffffff";

  // fill background

  this.fillBgRect(0, 0, width, height);

  // fill center to create border

  this.fillBgRect(0, this.border_size, width, height - this.border_size * 2);

}

//use native color

Graphics.prototype._fillRect = function (x, y, width, height, color) {

  this.ctx.setFillStyle(color)

  this.ctx.fillRect(x, y, width, height)

}

Graphics.prototype.fillFgRect = function (x, y, width, height) {

  this._fillRect(x, y, width, height, this.fg);

}

Graphics.prototype.fillBgRect = function (x, y, width, height) {

  this._fillRect(x, y, width, height, this.bg);

}

var PATTERNS = [

  [2, 1, 2, 2, 2, 2, 0, 0],  // 0

  [2, 2, 2, 1, 2, 2, 0, 0],  // 1

  [2, 2, 2, 2, 2, 1, 0, 0],  // 2

  [1, 2, 1, 2, 2, 3, 0, 0],  // 3

  [1, 2, 1, 3, 2, 2, 0, 0],  // 4

  [1, 3, 1, 2, 2, 2, 0, 0],  // 5

  [1, 2, 2, 2, 1, 3, 0, 0],  // 6

  [1, 2, 2, 3, 1, 2, 0, 0],  // 7

  [1, 3, 2, 2, 1, 2, 0, 0],  // 8

  [2, 2, 1, 2, 1, 3, 0, 0],  // 9

  [2, 2, 1, 3, 1, 2, 0, 0],  // 10

  [2, 3, 1, 2, 1, 2, 0, 0],  // 11

  [1, 1, 2, 2, 3, 2, 0, 0],  // 12

  [1, 2, 2, 1, 3, 2, 0, 0],  // 13

  [1, 2, 2, 2, 3, 1, 0, 0],  // 14

  [1, 1, 3, 2, 2, 2, 0, 0],  // 15

  [1, 2, 3, 1, 2, 2, 0, 0],  // 16

  [1, 2, 3, 2, 2, 1, 0, 0],  // 17

  [2, 2, 3, 2, 1, 1, 0, 0],  // 18

  [2, 2, 1, 1, 3, 2, 0, 0],  // 19

  [2, 2, 1, 2, 3, 1, 0, 0],  // 20

  [2, 1, 3, 2, 1, 2, 0, 0],  // 21

  [2, 2, 3, 1, 1, 2, 0, 0],  // 22

  [3, 1, 2, 1, 3, 1, 0, 0],  // 23

  [3, 1, 1, 2, 2, 2, 0, 0],  // 24

  [3, 2, 1, 1, 2, 2, 0, 0],  // 25

  [3, 2, 1, 2, 2, 1, 0, 0],  // 26

  [3, 1, 2, 2, 1, 2, 0, 0],  // 27

  [3, 2, 2, 1, 1, 2, 0, 0],  // 28

  [3, 2, 2, 2, 1, 1, 0, 0],  // 29

  [2, 1, 2, 1, 2, 3, 0, 0],  // 30

  [2, 1, 2, 3, 2, 1, 0, 0],  // 31

  [2, 3, 2, 1, 2, 1, 0, 0],  // 32

  [1, 1, 1, 3, 2, 3, 0, 0],  // 33

  [1, 3, 1, 1, 2, 3, 0, 0],  // 34

  [1, 3, 1, 3, 2, 1, 0, 0],  // 35

  [1, 1, 2, 3, 1, 3, 0, 0],  // 36

  [1, 3, 2, 1, 1, 3, 0, 0],  // 37

  [1, 3, 2, 3, 1, 1, 0, 0],  // 38

  [2, 1, 1, 3, 1, 3, 0, 0],  // 39

  [2, 3, 1, 1, 1, 3, 0, 0],  // 40

  [2, 3, 1, 3, 1, 1, 0, 0],  // 41

  [1, 1, 2, 1, 3, 3, 0, 0],  // 42

  [1, 1, 2, 3, 3, 1, 0, 0],  // 43

  [1, 3, 2, 1, 3, 1, 0, 0],  // 44

  [1, 1, 3, 1, 2, 3, 0, 0],  // 45

  [1, 1, 3, 3, 2, 1, 0, 0],  // 46

  [1, 3, 3, 1, 2, 1, 0, 0],  // 47

  [3, 1, 3, 1, 2, 1, 0, 0],  // 48

  [2, 1, 1, 3, 3, 1, 0, 0],  // 49

  [2, 3, 1, 1, 3, 1, 0, 0],  // 50

  [2, 1, 3, 1, 1, 3, 0, 0],  // 51

  [2, 1, 3, 3, 1, 1, 0, 0],  // 52

  [2, 1, 3, 1, 3, 1, 0, 0],  // 53

  [3, 1, 1, 1, 2, 3, 0, 0],  // 54

  [3, 1, 1, 3, 2, 1, 0, 0],  // 55

  [3, 3, 1, 1, 2, 1, 0, 0],  // 56

  [3, 1, 2, 1, 1, 3, 0, 0],  // 57

  [3, 1, 2, 3, 1, 1, 0, 0],  // 58

  [3, 3, 2, 1, 1, 1, 0, 0],  // 59

  [3, 1, 4, 1, 1, 1, 0, 0],  // 60

  [2, 2, 1, 4, 1, 1, 0, 0],  // 61

  [4, 3, 1, 1, 1, 1, 0, 0],  // 62

  [1, 1, 1, 2, 2, 4, 0, 0],  // 63

  [1, 1, 1, 4, 2, 2, 0, 0],  // 64

  [1, 2, 1, 1, 2, 4, 0, 0],  // 65

  [1, 2, 1, 4, 2, 1, 0, 0],  // 66

  [1, 4, 1, 1, 2, 2, 0, 0],  // 67

  [1, 4, 1, 2, 2, 1, 0, 0],  // 68

  [1, 1, 2, 2, 1, 4, 0, 0],  // 69

  [1, 1, 2, 4, 1, 2, 0, 0],  // 70

  [1, 2, 2, 1, 1, 4, 0, 0],  // 71

  [1, 2, 2, 4, 1, 1, 0, 0],  // 72

  [1, 4, 2, 1, 1, 2, 0, 0],  // 73

  [1, 4, 2, 2, 1, 1, 0, 0],  // 74

  [2, 4, 1, 2, 1, 1, 0, 0],  // 75

  [2, 2, 1, 1, 1, 4, 0, 0],  // 76

  [4, 1, 3, 1, 1, 1, 0, 0],  // 77

  [2, 4, 1, 1, 1, 2, 0, 0],  // 78

  [1, 3, 4, 1, 1, 1, 0, 0],  // 79

  [1, 1, 1, 2, 4, 2, 0, 0],  // 80

  [1, 2, 1, 1, 4, 2, 0, 0],  // 81

  [1, 2, 1, 2, 4, 1, 0, 0],  // 82

  [1, 1, 4, 2, 1, 2, 0, 0],  // 83

  [1, 2, 4, 1, 1, 2, 0, 0],  // 84

  [1, 2, 4, 2, 1, 1, 0, 0],  // 85

  [4, 1, 1, 2, 1, 2, 0, 0],  // 86

  [4, 2, 1, 1, 1, 2, 0, 0],  // 87

  [4, 2, 1, 2, 1, 1, 0, 0],  // 88

  [2, 1, 2, 1, 4, 1, 0, 0],  // 89

  [2, 1, 4, 1, 2, 1, 0, 0],  // 90

  [4, 1, 2, 1, 2, 1, 0, 0],  // 91

  [1, 1, 1, 1, 4, 3, 0, 0],  // 92

  [1, 1, 1, 3, 4, 1, 0, 0],  // 93

  [1, 3, 1, 1, 4, 1, 0, 0],  // 94

  [1, 1, 4, 1, 1, 3, 0, 0],  // 95

  [1, 1, 4, 3, 1, 1, 0, 0],  // 96

  [4, 1, 1, 1, 1, 3, 0, 0],  // 97

  [4, 1, 1, 3, 1, 1, 0, 0],  // 98

  [1, 1, 3, 1, 4, 1, 0, 0],  // 99

  [1, 1, 4, 1, 3, 1, 0, 0],  // 100

  [3, 1, 1, 1, 4, 1, 0, 0],  // 101

  [4, 1, 1, 1, 3, 1, 0, 0],  // 102

  [2, 1, 1, 4, 1, 2, 0, 0],  // 103

  [2, 1, 1, 2, 1, 4, 0, 0],  // 104

  [2, 1, 1, 2, 3, 2, 0, 0],  // 105

  [2, 3, 3, 1, 1, 1, 2, 0]  // 106

]

2.index.js中复制以下代码:

var barcode = require('./barcode');

function convert_length(length) {

    return Math.round(wx.getSystemInfoSync().windowWidth * length / 750);

}

function barc(id, code, width, height) {

    barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height))

}

module.exports = {

    barcode: barc

}

3.wxml中添加代码:

4.js中添加代码:

注意在设置条码的宽的时候一定要刚好合适,不然会不能扫描或者不容易扫描,调动宽度的时候要根据code的位数来调整。

上一篇下一篇

猜你喜欢

热点阅读