javascript - 读取图片文件,将获得的Buffer转换成String,再把String转Buffer写入到新图片文件,新图片文件无法正常显示
巴扎黑
巴扎黑 2017-04-10 16:59:17
[JavaScript讨论组]

代码如下

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.

巴扎黑
巴扎黑

全部回复(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里面,显示的结果如下:

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,结果如下:

可能你已经发现区别了……我们调整一下格式:

这也就是说图片的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;

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

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号