-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add code to create a png from a string
- Loading branch information
Amadeus Beckmann
committed
Oct 23, 2018
1 parent
fb35693
commit f7a6eb5
Showing
7 changed files
with
221 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 | ||
Copyright (c) 2018 lamadeus <[email protected]> (https://github.com/lamadeus) | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Buffer } from 'buffer'; | ||
import { createPng } from './png'; | ||
import { prependLength } from './utils'; | ||
|
||
|
||
/** | ||
* Encode the given data to png. | ||
* | ||
* @param {string} data | ||
* @returns {Promise<Buffer>} | ||
*/ | ||
export function encode(data) { | ||
const bytes = Buffer.from(data, 'utf8'); | ||
const pixelData = prependLength(bytes); | ||
|
||
return createPng(pixelData); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { Buffer } from 'buffer'; | ||
import { crc32 } from 'crc'; | ||
import zlib from 'zlib'; | ||
|
||
|
||
/** | ||
* PNG header. | ||
* | ||
* @type {Buffer} | ||
*/ | ||
const PNG_HEADER = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); | ||
|
||
/** | ||
* Max width of the png. | ||
* | ||
* @type {number} | ||
*/ | ||
const MAX_WIDTH = 1024; | ||
|
||
/** | ||
* Create a chunk of the given type with the given data. | ||
* | ||
* @param type | ||
* @param data | ||
* @returns {Buffer} | ||
*/ | ||
function createChunk(type, data) { | ||
const length = typeof data != 'undefined' ? data.length : 0; | ||
const chunk = Buffer.alloc(4 + 4 + length + 4); | ||
|
||
chunk.writeUInt32BE(length, 0); | ||
chunk.fill(type, 4, 8, 'utf8'); | ||
if (typeof data != 'undefined') { | ||
chunk.fill(data, 8, chunk.length - 4); | ||
} | ||
chunk.writeUInt32BE(crc32(chunk.slice(4, -4)), chunk.length - 4); | ||
|
||
return chunk; | ||
} | ||
|
||
/** | ||
* Create the IHDR chunk. | ||
* | ||
* @param width | ||
* @param height | ||
* @returns {Buffer} | ||
*/ | ||
function createIHDRChunk(width, height) { | ||
const data = Buffer.alloc(13); | ||
|
||
// Width | ||
data.writeUInt32BE(width); | ||
// Height | ||
data.writeUInt32BE(height, 4); | ||
// Bit depth | ||
data.writeUInt8(8, 8); | ||
// RGBA mode | ||
data.writeUInt8(6, 9); | ||
// No compression | ||
data.writeUInt8(0, 10); | ||
// No filter | ||
data.writeUInt8(0, 11); | ||
// No interlacing | ||
data.writeUInt8(0, 12); | ||
|
||
return createChunk('IHDR', data); | ||
} | ||
|
||
/** | ||
* Create the IDAT chunk. | ||
* | ||
* @param data | ||
* @returns {Buffer} | ||
*/ | ||
function createIDATChunk(data) { | ||
return createChunk('IDAT', data); | ||
} | ||
|
||
/** | ||
* Create the IEND chunk. | ||
* | ||
* @returns {Buffer} | ||
*/ | ||
function createIENDChunk() { | ||
return createChunk('IEND'); | ||
} | ||
|
||
/** | ||
* Create a png from the given pixel data. | ||
* | ||
* @param pixelData | ||
* @returns {Promise<Buffer>} | ||
*/ | ||
export function createPng(pixelData) { | ||
const length = pixelData.length + 4 - (pixelData.length % 4); | ||
const pixels = Math.ceil(length / 4); | ||
const width = Math.min(pixels, MAX_WIDTH); | ||
const height = Math.ceil(pixels / MAX_WIDTH); | ||
const bytesPerRow = width * 4; | ||
const buffer = Buffer.alloc((bytesPerRow + 1) * height); | ||
|
||
// Write pixel data to buffer | ||
for (let y = 0; y < height; y += 1) { | ||
const offset = y * bytesPerRow; | ||
const rowData = pixelData.slice(offset, offset + bytesPerRow); | ||
const rowStartX = offset + y + 1; | ||
const rowEndX = rowStartX + bytesPerRow; | ||
|
||
buffer.writeUInt8(0, offset + y); | ||
buffer.fill(rowData, rowStartX, rowEndX); | ||
} | ||
|
||
return new Promise((resolve, reject) => { | ||
zlib.deflate(buffer, (error, deflated) => { | ||
if (error) { | ||
reject(error); | ||
return; | ||
} | ||
|
||
resolve(Buffer.concat([ | ||
PNG_HEADER, | ||
createIHDRChunk(width, height), | ||
createIDATChunk(deflated), | ||
createIENDChunk(), | ||
])); | ||
}); | ||
}); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Buffer } from 'buffer'; | ||
|
||
|
||
/** | ||
* Prepend length to the data. | ||
* | ||
* @param data | ||
* @returns {Buffer} | ||
*/ | ||
export function prependLength(data) { | ||
const lengthAsBytes = Buffer.alloc(4); | ||
|
||
lengthAsBytes.writeUInt32BE(data.length); | ||
|
||
return Buffer.concat([lengthAsBytes, data]); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './es'; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "data-to-png", | ||
"version": "1.0.0", | ||
"description": "A Javascript utility that lets you encode any data to png.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/lamadeus/data-to-png.git" | ||
}, | ||
"keywords": [ | ||
"javascript", | ||
"encode", | ||
"decode", | ||
"png" | ||
], | ||
"author": "lamadeus <[email protected]>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/lamadeus/data-to-png/issues" | ||
}, | ||
"homepage": "https://github.com/lamadeus/data-to-png#readme", | ||
"dependencies": { | ||
"buffer": "^5.2.1", | ||
"crc": "^3.8.0", | ||
"zlib": "^1.0.5" | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | ||
# yarn lockfile v1 | ||
|
||
|
||
base64-js@^1.0.2: | ||
version "1.3.0" | ||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" | ||
|
||
buffer@^5.1.0, buffer@^5.2.1: | ||
version "5.2.1" | ||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" | ||
dependencies: | ||
base64-js "^1.0.2" | ||
ieee754 "^1.1.4" | ||
|
||
crc@^3.8.0: | ||
version "3.8.0" | ||
resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" | ||
dependencies: | ||
buffer "^5.1.0" | ||
|
||
ieee754@^1.1.4: | ||
version "1.1.12" | ||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" | ||
|
||
zlib@^1.0.5: | ||
version "1.0.5" | ||
resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0" |