From 03908ec9dbf75281eac97fc3ce872b3f042e9102 Mon Sep 17 00:00:00 2001 From: Dennis Riehle Date: Sun, 14 Apr 2019 23:32:10 +0200 Subject: [PATCH] Initial project --- .gitignore | 1 + lib/brother.js | 246 +++++++++++++++++++++++++++++++++++++ package-lock.json | 31 +++++ package.json | 13 ++ samples/name-tag-large.png | Bin 0 -> 18856 bytes samples/name-tag-large.prn | Bin 0 -> 95675 bytes samples/name-tag-small.png | Bin 0 -> 8484 bytes samples/name-tag-small.prn | Bin 0 -> 28343 bytes samples/print-samples.js | 7 ++ 9 files changed, 298 insertions(+) create mode 100644 .gitignore create mode 100644 lib/brother.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 samples/name-tag-large.png create mode 100644 samples/name-tag-large.prn create mode 100644 samples/name-tag-small.png create mode 100644 samples/name-tag-small.prn create mode 100644 samples/print-samples.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/lib/brother.js b/lib/brother.js new file mode 100644 index 0000000..f47373c --- /dev/null +++ b/lib/brother.js @@ -0,0 +1,246 @@ +const ipp = require('ipp'); +const util = require('util'); +const fs = require('fs'); +const pngparse = require('pngparse'); + +function wait(time) { + return new Promise(resolve => setTimeout(resolve, time)); +} + +async function doPrint(printerUrl, bufferToBePrinted) { + const printer = ipp.Printer(printerUrl); + const execute = util.promisify(printer.execute.bind(printer)); + const printerStatus = await execute('Get-Printer-Attributes', null); + + if (printerStatus['printer-attributes-tag']['printer-state'] === 'idle') { + // printer ready to work + const res = await execute( + 'Print-Job', + { + 'operation-attributes-tag': { + 'requesting-user-name': 'mobile', + 'job-name': 'label', + 'document-format': 'application/octet-stream', + }, + 'job-attributes-tag': { + copies: 1, + sides: 'one-sided', + 'orientation-requested': 'landscape', + }, + data: bufferToBePrinted, + }, + ); + + if (res.statusCode === 'successful-ok' || + res.statusCode === 'successful-ok-ignored-or-substituted-attributes') + { + const jobId = res['job-attributes-tag']['job-id']; + let tries = 0; + let job; + + await wait(500); + while (tries <= 50) { + tries += 1; + + // eslint-disable-next-line no-await-in-loop + job = await execute( + 'Get-Job-Attributes', + { 'operation-attributes-tag': { 'job-id': jobId } }, + ); + + if (job && job['job-attributes-tag']['job-state'] === 'completed') { + return job; + } + + // eslint-disable-next-line no-await-in-loop + await wait(1000); + } + + await execute('Cancel-Job', { + 'operation-attributes-tag': { + // "job-uri":jobUri, //uncomment this + //* / + 'printer-uri': printer.uri, // or uncomment this two lines - one of variants should work!!! + 'job-id': job['job-attributes-tag']['job-id'], + //* / + }, + }); + + console.log(`Job with id ${job['job-attributes-tag']['job-id']}is being canceled`); + throw new Error('Job is canceled - too many tries and job is not printed!'); + } else { + console.log(res); + throw new Error('Error sending job to printer!'); + } + } else { + throw new Error(`Printer ${printerStatus['printer-attributes-tag']['printer-name']} is not ready!`); + } +}; + +function convertToBlackAndWhiteMatrixImage(image, options) { + // convert image to matrix of pixels: + let rows = []; + + for (let y = 0; y < image.height; y++) { + let cols = []; + for (let x = 0; x < image.width; x++) { + let pos = x + image.width*y; + + + pos = pos * image.channels; + let pixel = 0; // white = 0, black = 1 + + // console.log(image.data[pos], image.data[pos+1], image.data[pos+2], image.data[pos+3]); + let threshold = options.blackwhiteThreshold; + let gray; + + // 1 channel : grayscale + // 2 channels: grayscale + alpha + // 3 channels: RGB + // 4 channels: RGBA + switch(image.channels) { + case 1: + if(image.data[pos] < threshold) pixel = 1; + break; + + case 2: + gray = image.data[pos] * image.data[pos+1]/255; + if(gray < threshold) pixel = 1; + break; + + case 3: + gray = 0.21*image.data[pos] + 0.72*image.data[pos+1] + 0.07*image.data[pos+2]; + if(gray < threshold) pixel = 1; + break; + + case 4: + gray = (0.21*image.data[pos] + 0.72*image.data[pos+1] + 0.07*image.data[pos+2]) * image.data[pos+3]/255; + if(gray < threshold) pixel = 1; + break; + } + + cols.push(pixel); + } + rows.push(cols); + } + + return { + height: image.height, + width: image.width, + data: rows + }; +} + +function rotateMatrixImage(bwMatrixImage) { + let rows = []; + for (let x = 0; x < bwMatrixImage.width; x++) { + let cols = []; + for (let y = bwMatrixImage.height - 1; y >= 0; y--) { + cols.push(bwMatrixImage.data[y][x]); + } + rows.push(cols); + } + + // noinspection JSSuspiciousNameCombination + return { + height: bwMatrixImage.width, + width: bwMatrixImage.height, + data: rows + }; +} + +function convertImageToDotlabel(bwMatrixImage) { + + // build header data for image + let data = [ + Buffer.alloc(400), // invalidate + Buffer.from([0x1b, 0x40]), // initialize + Buffer.from([0x1b, 0x69, 0x61, 0x01]), // switch to raster mode + Buffer.from([0x1b, 0x69, 0x21, 0x00]), // status notification + Buffer.from([0x1b, 0x69, 0x7a, 0x86, 0x0a, 0x3e, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00]), // 62mm continuous + Buffer.from([0x1b, 0x69, 0x4d, 0x40]), // select auto cut + Buffer.from([0x1b, 0x69, 0x41, 0x01]), // auto cut for each sheet + Buffer.from([0x1b, 0x69, 0x4b, 0x08]), // select cut at end + Buffer.from([0x1b, 0x69, 0x64, 0x23, 0x00]), // 35 dots margin + Buffer.from([0x4d, 0x00]), // disable compression + ]; + + // iterate over matrix imag + for (let y = 0; y < bwMatrixImage.height; y++) { + // each row has 3 bytes for the command and 90 bytes for data + let rowBuffer = Buffer.alloc(93); + + // command is 0x67 0x00 0x90 + rowBuffer[0] = 0x67; + rowBuffer[2] = 0x5A; // 90 + for (let x = 0; x < bwMatrixImage.width; x++) { + if(bwMatrixImage.data[y][x] == 1) { + // calculate current byte and bit + let byteNum = 93 - Math.floor(x / 8 + 3); + let bitOffset = x % 8; + // write data to buffer (which is currently 0x00-initialized) + rowBuffer[byteNum] |= (1 << bitOffset); + } + } + + data.push(rowBuffer); + } + + // end label with Z: + data.push(Buffer.from([0x1A])); + + // concat all buffers + let buf = Buffer.concat(data); + //console.log(buf.length, "length"); + return buf; +} + + +async function convert(img, options) { + // get options + let defaultOptions = { + landscape: false, + blackwhiteThreshold: 128 + }; + if (options == null) options = defaultOptions; + if (!options.landscape) options.landscape = defaultOptions.landscape; + if (!options.blackwhiteThreshold) options.blackwhiteThreshold = defaultOptions.blackwhiteThreshold; + + // image width cannot be more than 720 pixels + // can only store 90 bytes in a row with 8 pixels per byte so that's 720 pixels + if (!options.landscape) { + if(img.width > 720) throw new Error('Width cannot be more than 720 pixels'); + } else { + if(img.height > 720) throw new Error('Height cannot be more than 720 pixels'); + } + + // convert to black and white pixel matrix image (pbm style): + let bwMatrixImage = convertToBlackAndWhiteMatrixImage(img, options); + + // rotate image if landscape mode is requested + if(options.landscape){ + bwMatrixImage = rotateMatrixImage(bwMatrixImage); + } + + // convert to 'label image' or something that the label printer understands: + return convertImageToDotlabel(bwMatrixImage); +} + +module.exports = { + printPngFile: async function(printerUrl, filename, options) { + // read PNG file + let parseFile = util.promisify(pngparse.parseFile); + let img = await parseFile(filename); + + let printData = await convert(img, options); + return await doPrint(printerUrl, printData); + }, + printPngBuffer: async function (printerUrl, buffer, options) { + // read PNG buffer + let parseBuffer = util.promisify(pngparse.parseBuffer); + let img = await parseBuffer(filename); + + let printData = await convert(img, options); + return await doPrint(printerUrl, printData); + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..79a789f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,31 @@ +{ + "name": "brother-label-printer", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ipp/-/ipp-2.0.1.tgz", + "integrity": "sha512-p5dO2BXAVDnkv6IhUBupwydkq5/uw+DE+MGXnYzziNK1AtuLgbT9dFfJ3f8pA+J21n43TYipm6et/hTDEFJU/A==" + }, + "pngparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pngparse/-/pngparse-2.0.1.tgz", + "integrity": "sha1-hoUt5N40n077HoUudSVlXlrF37g=" + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "requires": { + "inherits": "2.0.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c1fca55 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "brother-label-printer", + "version": "0.0.1", + "description": "Create raster files to print via a Brother label printer", + "main": "lib/brother.js", + "author": "Dennis Riehle", + "license": "AGPL-3.0-or-later", + "dependencies": { + "ipp": "^2.0.1", + "pngparse": "^2.0.1", + "util": "^0.11.1" + } +} diff --git a/samples/name-tag-large.png b/samples/name-tag-large.png new file mode 100644 index 0000000000000000000000000000000000000000..75ecdf4b831bdc8e3514d36a477f7b492eecd8b7 GIT binary patch literal 18856 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 literal 0 HcmV?d00001 diff --git a/samples/name-tag-large.prn b/samples/name-tag-large.prn new file mode 100644 index 0000000000000000000000000000000000000000..622621f3c91579d64ac3cce2db97ba1dee85016f GIT binary patch literal 95675 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 literal 0 HcmV?d00001 diff --git a/samples/name-tag-small.png b/samples/name-tag-small.png new file mode 100644 index 0000000000000000000000000000000000000000..790245a6b7698bd7637cae9ae9a01e6128365287 GIT binary patch literal 8484 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 literal 0 HcmV?d00001 diff --git a/samples/print-samples.js b/samples/print-samples.js new file mode 100644 index 0000000..ae6e360 --- /dev/null +++ b/samples/print-samples.js @@ -0,0 +1,7 @@ +const brother = require('../index.js'); + +(async() => { + const printerUrl = 'http://192.168.178.71:631/ipp/print'; + await brother.printPngFile(printerUrl, './name-tag-small.png', {landscape: false}); + await brother.printPngFile(printerUrl, './name-tag-large.png', {landscape: true}); +})(); \ No newline at end of file