这个blob到PNG代码有什么问题?

时间:2017-05-16 02:33:29

标签: javascript png blob

我在这里使用PNG库:http://www.xarg.org/download/pnglib.js这里是我的代码:

var h=20;
var w=20;
var p = new PNGlib(h, w, 256);
var background = p.color(0, 0, 0, 0); // set the background transparent
for (var i = 0; i < h; i++) {
    for (var j = 0; j < w; j++) {
        p.buffer[p.index(i, j)] = p.color(0xcc, 0xee, 0x00);
    }
}
var pngStr = p.getDump();
var target1 = document.getElementById("target1");
target1.src = 'data:image/png;base64,'+btoa(pngStr);
//var pngStr = atob(target1.src.split(',')[1]);
//if(pngStr != pngStr2) alert("string don't match");
var pngbytes = new TextEncoder().encode(pngStr);
var blob = new Blob([pngbytes],  {type: 'image/png'});
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
var target2 = document.getElementById("target2");
target2.src = imageUrl;

从这个小提琴中可以看出:https://jsfiddle.net/1c0ggvfy/3/

base64编码版本有效,但blob版本没有。但这个做同样事情的小提琴确实适用于blob png: http://jsfiddle.net/ec9y6k9e/

我能看到的唯一区别是我必须将数据转换为二进制形式才能将其传递给Blob ...我已经尝试了几种不同的方法来做到这一点,但它似乎没有差。

编辑:正如Kaiido所指出的,问题似乎是TextEncoder。我之前尝试过遍历字符串来填充Uint8Array,但当时我遇到了第二个问题,即我在调用Blob构造函数时没有在第一个参数周围放置括号。这是工作代码:

var target1 = document.getElementById("target1");
target1.src = 'data:image/png;base64,'+p.getBase64();
var pngStr = atob(target1.src.split(',')[1]);
var bytes = new Uint8Array(pngStr.length);
for(var i=0; i<pngStr.length; i++){
    bytes[i]= pngStr.charCodeAt(i);
}
var blob = new Blob([bytes],  {type: 'image/png'});
var url = URL.createObjectURL(blob);
var target2 = document.getElementById("target2");
target2.src = url;

编辑2: 一个很好的答案包括: javascript中的字符是2个字节(https://mathiasbynens.be/notes/javascript-encoding),因此将它们视为等效于字节可能会导致意外结果。 TextEncoder是UTF-8(https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder),因此它表示代码点高于127的字符是两个字节,其中charCodeAt返回表示字符(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt)的整数 - 如果该整数是255或更小,它可以在Uint8Array中用于表示单个字节。

new TextEncoder().encode("\211")
->Uint8Array(2) [194, 137]

"\211".charCodeAt(0)
->137

0 个答案:

没有答案