Skip to content

Instantly share code, notes, and snippets.

@apisurfer
Last active March 26, 2016 09:23
Show Gist options
  • Save apisurfer/bc6e3a38079d06f73aad to your computer and use it in GitHub Desktop.
Save apisurfer/bc6e3a38079d06f73aad to your computer and use it in GitHub Desktop.
function decode(imageURL) {
"use strict"
function createShadowCanvas(width, height) {
var canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
return canvas
}
function wrapCanvas(canvas) {
var context = canvas.getContext('2d')
return {
context: context,
getData: function() { return context.getImageData(0, 0, canvas.width, canvas.height).data; },
draw: function(img) { return context.drawImage(img, 0, 0); },
}
}
function clearTrailingData(msgChunks) {
// no need for "leftover" byte; utf-16 uses 2 bytes so
// when we have a hanging byte it's for sure not being used; discard it
if (msgChunks.length % 2 !== 0) {
msgChunks.pop()
}
// Go from end and clear all 2byte pairs that are empty
var partsToTrim = 0
for (var i = msgChunks.length - 1; i >= 0; i -= 2) {
if (msgChunks[i] === 0 && msgChunks[i - 1] === 0) {
partsToTrim += 2
} else {
break
}
}
msgChunks.splice(-partsToTrim)
return msgChunks
}
function extractMessage(imageData) {
var msgChunks = []
var msg = ''
for (var i = 0; i < imageData.length; i += 4) {
msgChunks.push(
imageData[i],
imageData[i + 1],
imageData[i + 2]
)
}
msgChunks = clearTrailingData(msgChunks)
for (var i = 0; i < msgChunks.length; i += 2) {
msg += String.fromCharCode(
(msgChunks[i] << 8) + msgChunks[i + 1]
)
}
return msg
}
return new Promise(function(resolve, reject) {
var img = new Image();
img.crossOrigin = 'Anonymous' // enable cross origin content
img.onload = function() {
var wrappedCanvas = wrapCanvas(
createShadowCanvas(img.width, img.height)
)
wrappedCanvas.draw(img)
resolve(extractMessage(wrappedCanvas.getData()))
}
img.src = imageURL;
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment