Try this. It uses a somewhat esoteric image format (PAM), but you said any format is fine, and it really does work! It's not optimized or anything, so it's probably pretty slow, but hey, it works.
Edit: Okay, I optimized it a little...
var createPixel=(function() {
var table=[];
for(var i=0;i<26;i++) {
table.push(String.fromCharCode("A".charCodeAt(0)+i));
}
for(var i=0;i<26;i++) {
table.push(String.fromCharCode("a".charCodeAt(0)+i));
}
for(var i=0;i<10;i++) {
table.push(i.toString(10));
}
table.push("+");
table.push("/");
function b64encode(x) {
var bits=[];
for(var i=0;i<x.length;i++) {
var byte=x.charCodeAt(i);
for(var j=7;j>=0;j--) {
bits.push(byte&(1<<j));
}
}
var output=[];
for(var i=0;i<bits.length;i+=6) {
var section=bits.slice(i, i+6).map(
function(bit) { return bit?1:0; });
var required=6-section.length;
while(section.length<6) section.push(0);
section=(section[0]<<5)|
(section[1]<<4)|
(section[2]<<3)|
(section[3]<<2)|
(section[4]<<1)|
section[5];
output.push(table[section]);
if(required==2) {
output.push('=');
}else if(required==4) {
output.push('==');
}
}
output=output.join("");
return output;
}
if(window.btoa) {
b64encode=window.btoa;
}
return function createPixel(hexColor, opacity) {
var colorTuple=[
(hexColor&(0xFF<<16))>>16,
(hexColor&(0xFF<<8))>>8,
hexColor&0xFF,
Math.floor(opacity*255)
];
var data="P7\nWIDTH 1\nHEIGHT 1\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n";
colorTuple.forEach(function(tupleElement) {
data+=String.fromCharCode(tupleElement);
});
var base64DataURL="data:image/pam;base64,"+b64encode(data);
return base64DataURL;
}
})();
...but really, canvas
should work fine.
<canvas>
is actually faster than a JavaScript base64 encoder. – Aid