zoukankan      html  css  js  c++  java
  • 图片文件二进制编码合并与解析 Chris

      前边都是废话,直接从第四段开始看

      对于一些html的动画页面,canvas动画页面,会需要大量的图片文件。一张一张的从服务器获取图片,会影响页面的显示。

      怎样提高动画的效果,可以写一个load页面,然后通过js把图片先从服务器加载下来,避免在动画的时候,保证动画的流畅性。但是问题来了,在有大量图片的页面里,需要大量的请求数,在前端优化里就有提到要减少请求数,雪碧图很好,但是每次都要找设计给你拼好,当然,自己花点时间也是可以掌握这个东西,去做。但是有没有一种程序的方式,把图片整合,然后运用呢,重点来了,往下看。

      图片基本上都是一些二进制数据的拼接,对我要整合的就是这些二进制数据。前提知识点,nodejs(不需要很多)中的文件操作就是 fs 了,文件的读、写。接下来就是js中的 API ArrayBuffer,还有他的两个视图TypedArray和DataView。还有blob,都用的比较浅,我本人也是初接触这些。

      压缩阶段: 通过nodejs来进行压缩,很好的一点通过nodejs的 fs 读取到的文件是一个buffer数据。在前端用过js可以完美解析

      由于nodejs读取文件的一个便利性,所以压缩主要是,读取文件然后设置文件的存储规则,我的文件基本是每个图片包括四部分: 图片名称的大小(指字节数)+图片名称+图片文件的大小+图片的二进制文件,前边三部分通过Uint32来存储,存储方式是一个默认的小端字节序。

      上代码:

    var fs = require('fs');
    
    //所要读取文件的所在的位置 文件夹 
    var pat = './img/';
    //生成文件的保存位置与文件名,文件后缀可以任意
    var create = './cgppt/cg.sw';
    
    var buffer = new Buffer(0);
    var files = fs.readdirSync(pat);
    var count = files.length;
    files.forEach(function(filename) {
        count--;
        //读取文件数据
        var text = fs.readFileSync(pat + filename);
        //将文件的名称以及数据等信息压缩在一起
        var headerBuffer = header(filename, text);
        if(!!headerBuffer) {
            //将不同文件的二进制数据合并在一起,并写入文件
            buffer = Buffer.concat([buffer, headerBuffer]);
            if(count == 0) {
                fs.writeFile(create, buffer, (err) => {
                    if (err) throw err;
                    console.log('It\'s saved!');
                });
            }
        }
    });
    
    function header(filename, data) {   //整合单个文件数据
        var text = fs.readFileSync(pat + filename);
        var fileLen = numToBuffer(filename.length + 4);
        if(filename.search(/\.png$|\.jpg$/ig) != -1) {
            var file = strToBuffer('img/' + filename);
            var dataLen = numToBuffer(text.length);
            var data = new Buffer(text);
            var header = Buffer.concat([fileLen, file, dataLen, data]);
            return header;
        }
        return false;
    }
    
    function strToBuffer(data) {  //文件名称等信息规则
        var buffer = new Buffer(0);
        var str = data.toString();
        for(let i = str.length - 1; i >= 0; i--) {
            var num = str.charCodeAt(i);
            var strBuffer = numToBuffer(num);
            buffer = Buffer.concat([strBuffer, buffer]);
        }
        return buffer;
    }
    
    function numToBuffer(num) {  //以小端字节序方式将文件大小信息编入
        var buffer = new Buffer(4),
            ppp = [];
        ppp[0] = num % 256;
        ppp[1] = num % (256*256) / 256;
        ppp[2] = num / (256*256) % (256);
        ppp[3] = num / (256*256*256);
        for (var i = 0; i < buffer.length; i++) {
          buffer[i] = ppp[i];
        }
        return buffer;
    }
    View Code

      前端解析: 这里就是通过js来解析这个二进制文件,将通过blob和URL生成的一个链接赋值给img的src,也可以用于canvas动画

      

      关键代码

    while(len < data.byteLength) {
            //获取文件名的长度
        var f = data.getUint32(len, !0);
        len += 4;
        var l = '';
            //读取文件名
        for(var c = 0; c< f; c++) {
            var h = data.getUint32(len, !1);
            len += 4;
            l += String.fromCharCode(h);
        }
        //读取文件的长度
        var p = data.getUint32(len, !0);
            len += 4;
        //读取文件
            var d = new Uint8Array(buffer, len, p);
        //obj为文件名->文件的一个对象
            obj[l] = d;
            len += p,
        //文件名数组
            o.push(l),
        //文件数组
            a.push(d)
    }
                             
    View Code

    本文的大部分要点都来自于 阮一峰老师的JavaScript标准参考教程,还有MDN的web技术文档。

    本人前端小白,如有问题还请指正

    欢迎转载、交流

    参考链接: 阮一峰 二进制数据阮一峰 nodejs fs模块阮一峰 二进制数组

    JavaScript 标准参考教程(alpha)MDN

    如需转载请注明出处。
  • 相关阅读:
    第1年4月22日 IBInspectable巧妙用法 cornerRadius
    第1年4月15日
    第1年4月9日 Domain: com.apple.dt.MobileDeviceErrorDomain
    第1年4月7日 活体检测
    GPS 波段信号范围
    tomcat远程调试
    JdbcTemplate或hibernate动态建表
    jdk动态代理失效,事务自调用失效
    Tomcat 访问静态资源出现中文乱码解决办法(转)
    SQL Server 查看死锁进程(转)
  • 原文地址:https://www.cnblogs.com/dongcanliang/p/6134146.html
Copyright © 2011-2022 走看看