Decoding GIF and PNG colors without a Canvas
by Admiral Potato
HTML
<script src="https://wzrd.in/standalone/[email protected]"></script>
<script src="https://wzrd.in/standalone/[email protected]"></script>
<div>
<h2>gif transparent</h2>
<img data-name="gif"...
CSS
* {
font-family: monospace;
}
.colors {
display: inline-block;
background-color: #f00;
font-size: 0;
}
.colors span {
display: inline-block;
width: 1px;
height: 1px;
}
JavaScript
console.log('fast-png', window.fastPng);
console.log('omggif', window.omggif);
var images = Array.prototype.slice.apply(document.querySelectorAll('img'));
console.log('images', images);
var imageHandlerMap = {
gif: function(data) {
var reader = new omggif.GifReader(data);
var info = reader.frameInfo(0);
var buffer = new Uint8Array(
info.width * info.height * 4
);
reader.decodeAndBlitFrameRGBA(0, buffer);
console.log('GifReader', reader);
console.log('frameInfo', info);
return {
info: {
width: info.width,
height: info.height,
channels: 4
},
buffer: buffer
};
},
png: function(data) {
var decoded = fastPng.decode(data);
console.log('fastPng', decoded);
var info = {
width: decoded.width,
height: decoded.height,
channels: decoded.channels
};
var buffer = decoded.data;
if (decoded.palette) {
info.channels = decoded.palette[0].length;
var hasAlpha = info.channels === 4;
var pixels = info.width * info.height;
buffer = new Uint8Array(pixels * info.channels);
for (var i = 0; i < pixels; i++) {
var offset = i * info.channels;
var colorIndex = decoded.data[i];
var color = decoded.palette[colorIndex] || [0, 0, 0, 0];
buffer[offset + 0] = color[0];
buffer[offset + 1] = color[1];
buffer[offset + 2] = color[2];
if (hasAlpha) {
buffer[offset + 3] = color[3];
}
}
}
return {
info: info,
buffer: buffer
}
},
};
images.forEach(function(image) {
var base64Split = image.src.split(';base64,');
var type = base64Split[0].split('/').pop();
var dataString = atob(base64Split.pop());
var handler = imageHandlerMap[type];
var enc = new TextEncoder();
var dataBuffer = Uint8Array.from(
dataString,
c => c.charCodeAt(0)
);
console.log('type:', type);
console.log('imageHandlerMap:', imageHandlerMap);
try...