当前位置:   article > 正文

微信小程序生成条形码

小程序生成条形码

以下是处理过 wx.createCanvasContext()的,可以直接用

1. utils下新增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;
    }
    return CODESET.C;
  }

  //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(chr2));-----------------------------------
      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.fillStyle  = 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
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403

2. utils下新增codeIndex.js文件

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

function convert_length(length) {
    return Math.round(wx.getSystemInfoSync().windowWidth * length / 750);
}

function barc(context, code, width, height) {
  barcode.code128(context, code, convert_length(width), convert_length(height))
}

function qrc(id, code, width, height) {
    qrcode.api.draw(code, {
        ctx: wx.createCanvasContext(id),
        width: convert_length(width),
        height: convert_length(height)
    })
}

module.exports = {
    barcode: barc,
    qrcode: qrc
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3.业务wxml里新增元素

<canvas type="2d" id="barcode"></canvas>
  • 1

4. 业务js里新增方法

  // 创建条形码
  createBarcode: function () {
    const query = wx.createSelectorQuery()
    query.select('#barcode')
      .fields({
        node: true,
        size: true
      })
      .exec((res) => {
        const canvas = res[0].node
        if (!canvas) return
        /* 获取 canvas 实例 */
        const context = canvas.getContext('2d')
        const dpr = wx.getSystemInfoSync().pixelRatio
        canvas.width = res[0].width * dpr
        canvas.height = res[0].height * dpr
        context.scale(dpr, dpr)
        barCode.barcode(context, '123456', 440, 180)
      })
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

5. 业务样式

#barcode{
    display: block;
    width: 600rpx;
    height: 140rpx;
    margin: 0 auto;
    position: relative;
    z-index: 1;
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5. 提示:上述1/2的源码是经过处理的,直接用就可以了

这里标注一下都做了什么处理:原来源码是用的 wx.createCanvasContext(id),这个方法已经被废弃了。处理后改成了 wx.createSelectorQuery()方法,相应的,源码中的其他部分也要发生变化。

1. codeIndex.js

原来的:

function barc(id, code, width, height) {
    barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height))
}
  • 1
  • 2
  • 3

改为:

function barc(ctx, code, width, height) {
    barcode.code128(ctx, code, convert_length(width), convert_length(height))
}
  • 1
  • 2
  • 3
2.barCode.js

原来的

Graphics.prototype._fillRect = function(x, y, width, height, color) {
    this.ctx.setFillStyle(color)
    this.ctx.fillRect(x, y, width, height)
}
  • 1
  • 2
  • 3
  • 4

改为:

Graphics.prototype._fillRect = function(x, y, width, height, color) {
    this.ctx.fillStyle  = color;
    this.ctx.fillRect(x, y, width, height)
}
  • 1
  • 2
  • 3
  • 4
3.barCode.js

注掉 ctx.draw()

4.barCode.js

搜索result.push(codeValue(chr2))chr2改为chr1

 if (shifter != -1) {
     result.push(shifter);
     result.push(codeValue(chr1));
 }
  • 1
  • 2
  • 3
  • 4

源码: https://www.jianshu.com/p/3abec53a0bb2
处理方法原帖:https://developers.weixin.qq.com/community/develop/article/doc/0006cae8024368f5240fc99b15b813

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/905455
推荐阅读
相关标签
  

闽ICP备14008679号