Skip to content

Instantly share code, notes, and snippets.

@lmammino
Last active May 21, 2019 14:04
Show Gist options
  • Save lmammino/b85d2b285d76038ff759d532cc7c1d4c to your computer and use it in GitHub Desktop.
Save lmammino/b85d2b285d76038ff759d532cc7c1d4c to your computer and use it in GitHub Desktop.
Readable stream that allows you to display a png in the terminal
'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)
{
"name": "test",
"version": "1.0.0",
"dependencies": {
"chalk": "^2.4.2",
"png-js": "^0.1.1",
"readable-stream": "^3.3.0"
}
}
'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