读取图片文件,将获得的Buffer转换成String,再把String转Buffer写入到新图片文件,新图片文件无法正常显示

代码如下

var fs = require('fs')

var bf = fs.readFileSync('../../images/yun.jpg')
var str = bf.toString()
var cp = new Buffer(str)

console.log(bf);
// <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01
console.log(cp)
// <Buffer ef bf bd 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01
// 上下Buffer值不同

fs.writeFileSync('./hah.jpg', cp);

如果把toString、Buffer的encoding设置为base64,结果就正常了

原因大概已找到
stackoverflow

Using the default .toString, this will corrupt the data, because it will try to parse the image's binary data as UTF-8 data.

阅读 14.5k
1 个回答

在评论区犯了个蠢之后自己去测试了一下。代码和部分输出结果如下:

var fs = require('fs');
var l = console.log;
var bf = fs.readFileSync('./headicon.png');
l(bf);
// <Buffer 89 50 4e 47 0d 0a ... >
var str = bf.toString();
l(str);
// 控制台输出大量乱码天书QAQ
var cp = new Buffer(str);
l(cp);
// <Buffer ef bf bd 50 4e 47 ... >
fs.writeFileSync('./hah.png', bf);

直接输出获取到的bf的话结果肯定是对的,但是toString之后就不行了。
我又这样试了一下:

var fs = require('fs');
var l = console.log;
var bf = fs.readFileSync('./headicon.png');
l(bf);
var str = bf.toString();
var cp = new Buffer(str);
l(cp);
fs.writeFileSync('./hah.png', bf);
fs.writeFileSync('./hah2.png', str);
fs.writeFileSync('./hah3.png', cp);
fs.writeFileSync('./hah.txt', bf);
fs.writeFileSync('./hah2.txt', str);
fs.writeFileSync('./hah3.txt', cp);

分别写出6个文件。
hah.png是可以正常访问的图片,图片信息PNG 图像-26 KB
hah2.png不可以正常访问,预览会报错,图片信息PNG 图像-47 KB
hah3.png同hah2.png;
hah.txt同样是26kb大小的文件,放到sublime里面,显示的结果如下:
clipboard.png
hah2.txt大小47kb,sublime显示结果不用截图也可想而知,是efbf bd50 ...这些东西。
hah3.txt同hah2.txt。

然后问题在于,Buffer对象进行toString的时候发生了什么变化?
于是我换了一张12*12大小、体积为225B的图片,用以上的代码重新测试,测试结果:
hah.png是可以正常访问的图片,图片信息PNG-225 字节
hah2.png不可以正常访问,预览会报错,图片信息PNG-383 字节
hah3.png同hah2.png;
对比hah.txt与hah2.txt,结果如下:
clipboard.png
可能你已经发现区别了……我们调整一下格式:
clipboard.png
这也就是说图片的Buffer在进行toString()的时候,图片的数据信息因为种种原因发生了一些异变,同样的测试下,文本文件并不会造成这种问题。将生成的hah2.png重新进行了处理,用到以下代码(接上面的代码):

var bf2 = fs.readFileSync('./hah2.png');
var str2 = bf.toString();
var cp2 = new Buffer(str2);
fs.writeFileSync('./hah4.png', cp2);

这样输出得到的hah4.png的图片信息是PNG-383 字节,跟hah3.png的是完全相同的。
暂时得到了这样的结论,具体的体积为什么变大了还在测试,如果有结果会回来更新的QAQ;

嘛基本上已经有答案了,详见题主修改后的题目~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题