Last active
May 21, 2019 14:04
-
-
Save lmammino/b85d2b285d76038ff759d532cc7c1d4c to your computer and use it in GitHub Desktop.
Readable stream that allows you to display a png in the terminal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict' | |
| const { readFileSync } = require('fs') | |
| const PngTerm = require('./pngTerm') | |
| const [,, filePath] = process.argv | |
| const pngBuffer = readFileSync(filePath) | |
| const image = new PngTerm(pngBuffer) | |
| image.pipe(process.stdout) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "test", | |
| "version": "1.0.0", | |
| "dependencies": { | |
| "chalk": "^2.4.2", | |
| "png-js": "^0.1.1", | |
| "readable-stream": "^3.3.0" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict' | |
| const { Readable } = require('readable-stream') | |
| const chalk = require('chalk') | |
| const PNG = require('png-js') | |
| class PngTerm extends Readable { | |
| constructor (pngBuffer, options) { | |
| super(options) | |
| this._img = new PNG(pngBuffer) | |
| this._pixels = null | |
| this._x = 0 | |
| this._y = 0 | |
| } | |
| _read () { | |
| if (this._pixels === null) { | |
| this._loadPixels(() => this._pushNextPixel()) | |
| } else { | |
| this._pushNextPixel() | |
| } | |
| } | |
| _loadPixels (cb) { | |
| this._img.decode((data) => { | |
| this._pixels = [] | |
| // this is not optimal. We are copying the entire buffer to simplify the extraction of the data (using .shift() later) | |
| // Ideally this should be avoided by using a proper cursor over the original data. | |
| const dataArr = data.toJSON().data | |
| for (let y = 0; y < this._img.height; y++) { | |
| const row = [] | |
| for (let x = 0; x < this._img.width; x++) { | |
| const pixel = { | |
| r: dataArr.shift(), | |
| g: dataArr.shift(), | |
| b: dataArr.shift(), | |
| a: dataArr.shift() | |
| } | |
| row.push(pixel) | |
| } | |
| this._pixels.push(row) | |
| } | |
| cb() | |
| }) | |
| } | |
| _pushNextPixel () { | |
| const { r, g, b } = this._pixels[this._y][this._x] | |
| this.push(chalk.bgRgb(r, g, b)(' ')) | |
| this._x += 1 | |
| if (this._x === this._img.width) { | |
| this._y += 1 | |
| this.push('\n\r') | |
| if (this._y === this._img.height) { | |
| return this.push(null) // stream is over | |
| } | |
| this._x = 0 | |
| } | |
| } | |
| } | |
| module.exports = PngTerm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment