label.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. var app = getApp();
  2. var tsc = require("../../utils/tsc.js");
  3. var encode = require("../../utils/encoding.js");
  4. function convertToGrayscale(data) {
  5. let g = 0
  6. for (let i = 0; i < data.length; i += 4) {
  7. g = (data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11)
  8. data[i] = g
  9. data[i + 1] = g
  10. data[i + 2] = g
  11. }
  12. return data
  13. }
  14. function inArray(arr, key, val) {
  15. for (let i = 0; i < arr.length; i++) {
  16. if (arr[i][key] === val) {
  17. return i;
  18. }
  19. }
  20. return -1;
  21. }
  22. // ArrayBuffer转16进度字符串示例
  23. function ab2hex(buffer) {
  24. var hexArr = Array.prototype.map.call(
  25. new Uint8Array(buffer),
  26. function (bit) {
  27. return ('00' + bit.toString(16)).slice(-2)
  28. }
  29. )
  30. return hexArr.join('');
  31. }
  32. // function convertToGrayscale(data) {
  33. // let g = 0
  34. // for (let i = 0; i < data.length; i += 4) {
  35. // g = (data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11)
  36. // data[i] = g
  37. // data[i + 1] = g
  38. // data[i + 2] = g
  39. // }
  40. // return data
  41. // }
  42. function setPixel(data, offset, value) {
  43. data[offset] = value;
  44. data[offset + 1] = value;
  45. data[offset + 2] = value;
  46. }
  47. function adjustPixel(data, offset, value) {
  48. data[offset] += value;
  49. }
  50. // 彩色图转成单色图
  51. function convertToMonoImage(width, height, data, shake) {
  52. let g = 0
  53. let e = 0
  54. for (let i = 0; i < data.length; i += 4) {
  55. data[i] = (data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11);
  56. }
  57. for (let y = 0; y < height; y++) {
  58. for (let x = 0; x < width; x++) {
  59. let dataOffset = (width * y + x) * 4;
  60. g = data[dataOffset];
  61. if (g >= 150) { // 灰色转黑白的阈值, 可以调整打印效果
  62. e = g - 255;
  63. setPixel(data, dataOffset, 255);
  64. } else {
  65. e = g;
  66. setPixel(data, dataOffset, 0);
  67. }
  68. if (!shake)
  69. continue;
  70. if (x < width - 1 && y < height - 1) {
  71. //右边像素处理
  72. data[(width * y + x + 1) * 4] += 7 * e / 16;
  73. //下
  74. data[(width * (y + 1) + x) * 4] += 5 * e / 16;
  75. //右下
  76. data[(width * (y + 1) + x + 1) * 4] += e / 16;
  77. //左下
  78. if (x > 0) {
  79. data[(width * (y + 1) + x - 1) * 4] += 3 * e / 16;
  80. }
  81. } else if (x == width - 1 && y < height - 1) {
  82. //下方像素处理
  83. data[(width * (y + 1) + x) * 4] += 5 * e / 16;
  84. } else if (x < width - 1 && y == height - 1) {
  85. //右边像素处理
  86. data[(width * y + x + 1) * 4] += 7 * e / 16;
  87. }
  88. }
  89. }
  90. return data
  91. }
  92. Page({
  93. /**
  94. * 页面的初始数据
  95. */
  96. data: {
  97. looptime: 0,
  98. currentTime: 1,
  99. lastData: 0,
  100. oneTimeData: 0,
  101. buffSize: [],
  102. buffIndex: 0,//发送字节数下标
  103. printNum: [],
  104. printNumIndex: 0,
  105. printerNum: 1,
  106. currentPrint: 1,
  107. isLabelSend: false,
  108. isQuery: false,
  109. imageSrc: '../../imags/wechat.jpg',
  110. jpgSrc: '../../imags/flower2.jpg',
  111. canvasWidth: 100,
  112. canvasHeight: 100,
  113. jpgWidth: 200,
  114. jpgHeight: 200,
  115. },
  116. /**
  117. * 生命周期函数--监听页面加载
  118. */
  119. onLoad: function (options) {
  120. }, initPhoto: function () {//初始化画布数据
  121. //创建一个png格式
  122. var that = this
  123. const ctx_out = wx.createCanvasContext('canvasOut', this);
  124. var png = that.data.imageSrc;
  125. wx.getImageInfo({
  126. src: png,
  127. success(res) {
  128. that.setData({
  129. canvasWidth: res.width,
  130. canvasHeight: res.height,
  131. });
  132. console.log("画布宽度" + res.width, "画布高度" + res.height);
  133. // ctx_out.setFillStyle('#ffffff')
  134. // ctx_out.setStrokeStyle('rgba(1,1,1,0)')
  135. // ctx_out.fill()
  136. //ctx_out.drawImage(png, 0, 0, res.width, res.height);
  137. ctx_out.drawImage(png, 0, 0);
  138. ctx_out.draw();
  139. }
  140. })
  141. //创建一个jpg格式图片
  142. const ctx_jpg = wx.createCanvasContext('canvasJPG', this);
  143. var jpg_width = that.data.jpgWidth;
  144. var jpg_height = that.data.jpgHeight;
  145. var img = that.data.jpgSrc;
  146. wx.getImageInfo({
  147. src: img,
  148. success(res) {
  149. that.setData({
  150. jpgWidth: res.width,
  151. jpgHeight: res.height,
  152. });
  153. console.log("JPG画布宽度" + res.width, "JPG画布高度" + res.height);
  154. ctx_jpg.drawImage(img, 0, 0, res.width, res.height);
  155. ctx_jpg.draw();
  156. }
  157. })
  158. },
  159. labelTest: function () { //标签测试
  160. var that = this;
  161. var canvasWidth = that.data.canvasWidth
  162. var canvasHeight = that.data.canvasHeight
  163. var command = tsc.jpPrinter.createNew()
  164. command.setCls()//清除缓冲区,防止下一个没生效
  165. command.setSize(58, 30)//设置标签大小,单位mm.具体参数请用尺子量一下
  166. command.setGap(0)//设置两个标签之间的间隙,单位mm.具体参数请用尺子量一下
  167. command.setCls()//清除缓冲区
  168. command.setBox(10, 10, 464, 230, 5)//绘制一个边框
  169. command.setBar(10, 75, 455, 5);//绘制一条黑线
  170. command.setText(150, 20, "TSS24.BF2", 0, 2, 2, "棒棒糖")//绘制文字
  171. command.setText(340, 20, "TSS24.BF2", 0, 2, 2, "8 元")//绘制文字
  172. command.setText(360, 40, "TSS24.BF2", 0, 1, 1, ".8")//绘制文字
  173. command.setText(50, 100, "TSS24.BF2", 0, 1, 1, "单位:______")//绘制文字
  174. command.setText(140, 90, "TSS24.BF2", 0, 1, 1, "包")//绘制文字
  175. command.setText(50, 140, "TSS24.BF2", 0, 1, 1, "重量:______")//绘制文字
  176. command.setText(140, 130, "TSS24.BF2", 0, 1, 1, "500g")//绘制文字
  177. command.setText(50, 170, "TSS24.BF2", 0, 1, 1, "条码:")//绘制文字
  178. command.setBarCode(120, 170, "128", 48, 0, 0, 2, 2, "12345678")//绘制code128条码
  179. command.setBar(300, 80, 5, 150);//绘制一条黑线
  180. command.setQrcode(320, 90, "L", 5, "A", "http://www.howbest.cn/cn/")//绘制一个二维码
  181. command.setPagePrint()//执行打印指令
  182. that.setData({
  183. isLabelSend: true
  184. })
  185. that.prepareSend(command.getData())
  186. },
  187. printPhoto: function () {//打印bitmap,图片内容不建议太大,小程序限制传输的字节数为20byte
  188. var that = this;
  189. var canvasWidth = that.data.canvasWidth
  190. var canvasHeight = that.data.canvasHeight
  191. var command = tsc.jpPrinter.createNew()
  192. command.setCls()
  193. command.setSize(30, 30)
  194. command.setGap(0)
  195. command.setCls()
  196. wx.canvasGetImageData({
  197. canvasId: 'canvasOut',
  198. x: 0,
  199. y: 0,
  200. width: canvasWidth,
  201. height: canvasHeight,
  202. success: function (res) {
  203. console.log("获取画布数据成功")
  204. command.setBitmap(0, 0, 0, res)
  205. command.setPrint(1)
  206. that.prepareSend(command.getData())//发送数据
  207. },
  208. complete: function (res) {
  209. console.log("finish")
  210. },
  211. fail: function (res) {
  212. console.log(res)
  213. wx.showToast({
  214. title: '获取画布数据失败',
  215. icon: 'none',
  216. })
  217. }
  218. })
  219. },
  220. printJPGPhoto: function () {
  221. var that = this;
  222. var canvasWidth = that.data.jpgWidth
  223. var canvasHeight = that.data.jpgHeight
  224. //抖动处理JPG图片
  225. const cfg = {
  226. x: 0,
  227. y: 0,
  228. width: canvasWidth,
  229. height: canvasHeight,
  230. }
  231. wx.canvasGetImageData({
  232. canvasId: 'canvasJPG',
  233. ...cfg,
  234. success: (res) => {
  235. //const data = convertToGrayscale(res.data)
  236. const data = convertToMonoImage(res.width, res.height, res.data, true);
  237. wx.canvasPutImageData({
  238. canvasId: 'canvasJPG',
  239. data,
  240. ...cfg,
  241. success: (res) => {
  242. console.log(res)
  243. console.log('deal graphic width: ' + cfg.width)
  244. console.log('deal graphic width: ' + cfg.height)
  245. that.printerJPG();
  246. },
  247. fail: (err) => {
  248. console.error(err)
  249. }
  250. })
  251. },
  252. fail: (err) => {
  253. console.error(err)
  254. }
  255. })
  256. },
  257. printerJPG: function () {
  258. var that = this;
  259. var canvasWidth = that.data.jpgWidth
  260. var canvasHeight = that.data.jpgHeight
  261. var command = tsc.jpPrinter.createNew()
  262. command.setCls()
  263. command.setSize(30, 30)
  264. command.setGap(0)
  265. command.setCls()
  266. wx.canvasGetImageData({
  267. canvasId: 'canvasJPG',
  268. x: 0,
  269. y: 0,
  270. width: canvasWidth,
  271. height: canvasHeight,
  272. success: function (res) {
  273. console.log("获取画布数据成功")
  274. command.setBitmap(60, 0, 1, res)
  275. command.setPrint(1)
  276. that.prepareSend(command.getData())//发送数据
  277. },
  278. complete: function (res) {
  279. console.log("finish")
  280. },
  281. fail: function (res) {
  282. console.log(res)
  283. wx.showToast({
  284. title: '获取画布数据失败',
  285. icon: 'none',
  286. })
  287. }
  288. })
  289. },
  290. prepareSend: function (buff) { //准备发送,根据每次发送字节数来处理分包数量
  291. //console.log(buff)
  292. var that = this
  293. var time = that.data.oneTimeData
  294. var looptime = parseInt(buff.length / time);
  295. var lastData = parseInt(buff.length % time);
  296. //console.log(looptime + "---" + lastData)
  297. that.setData({
  298. looptime: looptime + 1,
  299. lastData: lastData,
  300. currentTime: 1,
  301. })
  302. that.Send(buff)
  303. },
  304. queryStatus: function () {//查询打印机状态
  305. var that = this
  306. var buf;
  307. var dateView;
  308. /*
  309. n = 1:传送打印机状态
  310. n = 2:传送脱机状态
  311. n = 3:传送错误状态
  312. n = 4:传送纸传感器状态
  313. */
  314. buf = new ArrayBuffer(5)
  315. dateView = new DataView(buf)
  316. dateView.setUint8(0, 27)
  317. dateView.setUint8(1, 33)
  318. dateView.setUint8(2, 63)
  319. dateView.setUint8(3, 13)
  320. dateView.setUint8(4, 10)
  321. wx.writeBLECharacteristicValue({
  322. deviceId: app.BLEInformation.deviceId,
  323. serviceId: app.BLEInformation.writeServiceId,
  324. characteristicId: app.BLEInformation.writeCharaterId,
  325. value: buf,
  326. success: function (res) {
  327. console.log("发送成功")
  328. that.setData({
  329. isQuery: true
  330. })
  331. },
  332. fail: function (e) {
  333. wx.showToast({
  334. title: '发送失败',
  335. icon: 'none',
  336. })
  337. //console.log(e)
  338. return;
  339. },
  340. complete: function () {
  341. }
  342. })
  343. wx.notifyBLECharacteristicValueChange({
  344. deviceId: app.BLEInformation.deviceId,
  345. serviceId: app.BLEInformation.notifyServiceId,
  346. characteristicId: app.BLEInformation.notifyCharaterId,
  347. state: true,
  348. success: function (res) {
  349. wx.onBLECharacteristicValueChange(function (r) {
  350. console.log(`characteristic ${r.characteristicId} has changed, now is ${r}`)
  351. var result = ab2hex(r.value)
  352. console.log("返回" + result)
  353. var tip = ''
  354. if (result == 0) {//正常
  355. tip = "正常"
  356. } else if (result == 4) {//缺纸
  357. tip = "缺纸"
  358. } else if (result == 5) {//开盖、缺纸
  359. tip = "开盖、缺纸"
  360. } else if (result == 41) {
  361. tip = "开盖"
  362. }else if (result == 40) {//其他错误
  363. tip = "其他错误"
  364. } else {//未处理错误
  365. tip = "未知错误"
  366. }
  367. wx.showModal({
  368. title: '打印机状态',
  369. content: tip,
  370. showCancel: false
  371. })
  372. })
  373. },
  374. fail: function (e) {
  375. wx.showModal({
  376. title: '打印机状态',
  377. content: '获取失败',
  378. showCancel: false
  379. })
  380. console.log(e)
  381. },
  382. complete: function (e) {
  383. that.setData({
  384. isQuery: false
  385. })
  386. console.log("执行完成")
  387. }
  388. })
  389. },
  390. Send: function (buff) { //分包发送
  391. var that = this
  392. var currentTime = that.data.currentTime
  393. var loopTime = that.data.looptime
  394. var lastData = that.data.lastData
  395. var onTimeData = that.data.oneTimeData
  396. var printNum = that.data.printerNum
  397. var currentPrint = that.data.currentPrint
  398. var buf
  399. var dataView
  400. if (currentTime < loopTime) {
  401. buf = new ArrayBuffer(onTimeData)
  402. dataView = new DataView(buf)
  403. for (var i = 0; i < onTimeData; ++i) {
  404. dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
  405. }
  406. } else {
  407. buf = new ArrayBuffer(lastData)
  408. dataView = new DataView(buf)
  409. for (var i = 0; i < lastData; ++i) {
  410. dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
  411. }
  412. }
  413. //console.log("第" + currentTime + "次发送数据大小为:" + buf.byteLength)
  414. wx.writeBLECharacteristicValue({
  415. deviceId: app.BLEInformation.deviceId,
  416. serviceId: app.BLEInformation.writeServiceId,
  417. characteristicId: app.BLEInformation.writeCharaterId,
  418. value: buf,
  419. success: function (res) {
  420. if (currentPrint == printNum) {
  421. wx.showToast({
  422. title: '已打印第' + currentPrint + '张成功',
  423. })
  424. }
  425. //console.log(res)
  426. },
  427. fail: function (e) {
  428. wx.showToast({
  429. title: '打印第' + currentPrint + '张失败',
  430. icon: 'none',
  431. })
  432. //console.log(e)
  433. },
  434. complete: function () {
  435. currentTime++
  436. if (currentTime <= loopTime) {
  437. that.setData({
  438. currentTime: currentTime
  439. })
  440. that.Send(buff)
  441. } else {
  442. // wx.showToast({
  443. // title: '已打印第' + currentPrint + '张',
  444. // })`
  445. if (currentPrint == printNum) {
  446. that.setData({
  447. looptime: 0,
  448. lastData: 0,
  449. currentTime: 1,
  450. isLabelSend: false,
  451. currentPrint: 1
  452. })
  453. } else {
  454. currentPrint++
  455. that.setData({
  456. currentPrint: currentPrint,
  457. currentTime: 1,
  458. })
  459. that.Send(buff)
  460. }
  461. }
  462. }
  463. })
  464. },
  465. /**
  466. * 生命周期函数--监听页面初次渲染完成
  467. */
  468. onReady: function () {
  469. var list = []
  470. var numList = []
  471. var j = 0
  472. for (var i = 20; i < 200; i += 10) {
  473. list[j] = i;
  474. j++
  475. }
  476. for (var i = 1; i < 10; i++) {
  477. numList[i - 1] = i
  478. }
  479. this.setData({
  480. buffSize: list,
  481. oneTimeData: list[0],
  482. printNum: numList,
  483. printerNum: numList[0]
  484. })
  485. this.initPhoto();
  486. },
  487. /**
  488. * 生命周期函数--监听页面显示
  489. */
  490. onShow: function () {
  491. },
  492. buffBindChange: function (res) { //更改打印字节数
  493. var index = res.detail.value
  494. var time = this.data.buffSize[index]
  495. this.setData({
  496. buffIndex: index,
  497. oneTimeData: time
  498. })
  499. },
  500. printNumBindChange: function (res) { //更改打印份数
  501. var index = res.detail.value
  502. var num = this.data.printNum[index]
  503. this.setData({
  504. printNumIndex: index,
  505. printerNum: num
  506. })
  507. },
  508. /**
  509. * 生命周期函数--监听页面隐藏
  510. */
  511. onHide: function () {
  512. },
  513. /**
  514. * 生命周期函数--监听页面卸载
  515. */
  516. onUnload: function () {
  517. //关闭蓝牙连接
  518. // wx.closeBLEConnection({
  519. // deviceId: app.BLEInformation.deviceId,
  520. // success: function(res) {
  521. // console.log("关闭蓝牙成功")
  522. // },
  523. // })
  524. },
  525. /**
  526. * 页面相关事件处理函数--监听用户下拉动作
  527. */
  528. onPullDownRefresh: function () {
  529. },
  530. /**
  531. * 页面上拉触底事件的处理函数
  532. */
  533. onReachBottom: function () {
  534. },
  535. /**
  536. * 用户点击右上角分享
  537. */
  538. onShareAppMessage: function () {
  539. }
  540. })