我试图在JavaScript和Ruby中为图像文件生成相同的base64数据。不幸的是,两者都输出了两个非常不同的值。
在Ruby中我这样做:
Base64.encode64(File.binread('test.png'));
然后在JavaScript中:
var image = new Image();
image.src = 'http://localhost:8000/test.png';
$(image).load(function() {
var canvas, context, base64ImageData;
canvas = document.createElement('canvas');
context = canvas.getContext('2d');
canvas.width = this.width;
canvas.height = this.height;
context.drawImage(this, 0, 0);
imageData = canvas.toDataURL('image/png').replace(/data:image\/[a-z]+;base64,/, '');
console.log(imageData);
});
知道为什么这些输出有所不同?
答案 0 :(得分:3)
当你在Ruby中加载图像时,没有任何修改的二进制文件将直接编码到base-64。
当您在浏览器中加载图像时,它会对图像应用一些处理,然后才能将它用于画布:
当您将图像绘制到画布时,位图值已经更改,并且不一定与在将其作为图像加载之前编码的位图相同(如果文件中有Alpha通道)这可能会影响绘制到画布时的颜色值 - 画布在这方面有点奇怪..)。
随着颜色值的改变,画布中的结果字符串自然也会有所不同,在你进入重新编码位图的阶段之前(因为PNG是无损的,编码/压缩应该是完全相同的,但是可能存在的因素取决于影响它的浏览器实现。测试,将黑色未处理的画布保存为PNG并与应用程序中的类似图像进行比较 - 所有值应为0,包括alpha和相同的大小疗程)。
避免这种情况的唯一方法是直接处理二进制数据。这当然有点矫枉过正(至少一般来说)和浏览器中相对较慢的过程。
在某些情况下可行的解决方案是从图像文件中删除任何ICC配置文件。要在没有ICC的情况下从Photoshop保存图像,请选择" Save for web .."在文件菜单中。
答案 1 :(得分:1)
浏览器在保存画布时重新编码图像。
它不会为您渲染的文件生成相同的编码。
答案 2 :(得分:0)
所以我实际上最终解决了这个......
幸运的是,我正在使用imgcache.js使用FileSystem API在本地文件系统中缓存图像。我的解决方案是使用此API(并且imgcache.js可以轻松实现)从文件的实际缓存副本中获取base64数据。代码如下所示:
var imageUrl = 'http://localhost:8000/test.png';
ImgCache.init(function() {
ImgCache.cacheFile(imageUrl, function() {
ImgCache.getCachedFile(imageUrl, function(url, fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
console.log($.md5(this.result.replace(/data:image\/[a-z]+;base64,/, '')));
};
reader.readAsDataURL(file);
});
});
});
});
另外,非常重要的是,我必须从Ruby中的base64中删除换行符:
Base64.encode64(File.binread('test.png')).gsub("\n", '');