最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端玩转GIF图片压缩

    正文概述 掘金(凉城a)   2021-03-04   530

    前言

    最近接到上级通知,文件如下:

    奉天承运,公司诏曰:介于前端组表现优异,后端组忙里偷不出闲,GIF压缩这一块特赐予前端组。

    钦此,

    不一会后端群众就送来了亲切的问候,千万个草泥马在我的心中奔跑

    吃瓜不嫌事大

    骂骂咧咧过后,平复下心情,想想思路

    抛砖引玉-压缩图片

    之前做过图片压缩,无非是把file->base64->新建canvas画图->导出canvas->转file

    • input 读取到 image/file ,使用 FileReader 将其转换为 base64 编码
    • 新建 img ,使其 src 指向刚刚的 base64
    • 新建 canvas ,将 img 画到 canvas 上
    • 利用 canvas.toDataURL/toBlob 将 canvas 导出为 base64 或 Blob
    • 将 base64 或 Blob 转化为 File

    这是常规思路,照这个走走看结果如何

    预览图片

    实现本地图片预览有两种方法

    1.new FileReader

    FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 FileBlob 对象指定要读取的文件或数据。

    语法

    其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。

    附注

    重要提示: FileReader仅用于以安全的方式从用户(远程)系统读取文件内容 它不能用于从文件系统中按路径名简单地读取文件。 要在JavaScript中按路径名读取文件,应使用标准Ajax解决方案进行服务器端文件读取,如果读取跨域,则使用CORS权限。

    前端玩转GIF图片压缩

    function handleFile(e) {
      var file = e.files[0];
      var fileReader = new FileReader();
      var img = document.getElementById(id);
      fileReader.onload = function(e) {
        img.src = e.target.result;
      }
      fileReader.readAsDataURL(file);
    }
    

    2.createObjectURL

    window.URL.createObjectURL

    概述

    URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。

    语法

    前端玩转GIF图片压缩 objectURL = window.URL.createObjectURL(blob);

    • blob参数是一个File对象或者Blob对象.
    • objectURL是生成的对象URL.通过这个URL,可以获取到所指定文件的完整内容.

    附注

    在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。

    浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

    function handleFile() {
      var url = window.URL.createObjectURL(file);
      var img = document.getElementById(id);
      img.src = url
      img.onload = function () {
        // 加载完成后销毁url,节省性能
        window.URL.revokeObjectURL(videoUrl);
      }
    }
    

    压缩图片

    HTMLCanvasElement.toDataURL()

    概述

    HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。

    • 如果画布的高度或宽度是0,那么会返回字符串“data:,”。
    • 如果传入的类型非“image/png”,但是返回的值以“data:image/png”开头,那么该传入的类型是不支持的。
    • Chrome支持“image/webp”类型。

    语法

    canvas.toDataURL(type, encoderOptions);
    type:图片格式
    encoderOptions:在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
    var mediumQuality = canvas.toDataURL("image/jpeg", 0.5);
    var lowQuality = canvas.toDataURL("image/jpeg", 0.1);
    

    附注

    前端玩转GIF图片压缩

    function image2Base64(img) {
      var canvas = document.createElement("canvas");
      let w = img.width;
      let h = img.height;
      let quality = 0.5; 
      canvas.width = w;
      canvas.height = h;
      var ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, w, h);
      var dataURL = canvas.toDataURL("image/png",quality);
      return dataURL;
    }
    // 将dataURL转化为file对象的函数
    function dataURLtoFile(dataurl, filename) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, { type: mime });
    }
    

    真知灼见-GIF图片压缩

    准备

    查阅资料

    在实际情况中,GIF图具有下面的特征

    (1)一张图像最多只会包含256个RGB值。

    (2)在一张连续动态GIF里,每一帧之间信息差异不大,颜色是被大量重复使用的。

    思考分析

    • 在存储时,我们用一个公共的索引表,把图片中用到的颜色提取出来,组成一个调色盘,这样,在存储真正的图片点阵时,只需要存储每个点在调色盘里的索引值。

    • 如果调色盘放在文件头,作为所有帧公用的信息,就是公共(全局)调色盘,如果放在每一帧的帧信息中,就是局部调色盘。GIF格式允许两种调色盘同时存在,在没有局部调色盘的情况下,使用公共调色盘来渲染。

    • 这样,我们可以用调色盘里的索引来代表实际的颜色值。

    • 一个256色的调色盘,24bit的颜色只需要用9bit就可以表达了。

    • 调色盘还可以进一步减少,128色,64色,etc,相应的压缩率就会越来越大……

    • 所谓的每一帧,其实和分辨率差不多,帧数过快也就越清晰同时文件也也大

    得出结论

    经过查阅资料和分析可以得出想要压缩GIF无非从两方面着手

    1. 如果可以接受牺牲图像的部分视觉效果,就可以通过减色来对图像做进一步压缩。

    2. 如果可以接受顿挫感(也就是不怎么流畅),就可以通过减帧来对图像做进一步压缩。

    实践

    1.通过减帧来对图像做进一步压缩。

    原图: 前端玩转GIF图片压缩 可以看到原图大小1823814b

    //compressGif方法见附录
    compressGif (file,256,classId, uploadId)
    

    减帧压缩后: 前端玩转GIF图片压缩 可以看到减帧压缩后大小为1617818b

    2.在减帧的基础上通过减色来对图像做进一步压缩。

    减帧减色压缩后:(极限值只有黑白2种颜色) 前端玩转GIF图片压缩

    //compressGif方法见附录
    compressGif (file,2,classId, uploadId)
    

    可以看到减帧压缩后大小为48653b,压缩结果还是非常可观的!

    gifmin.js:一个GIF图片压缩库,如果对你有帮助,请点亮你的小星星⭐⭐⭐哦~(疯狂暗示)

    超级简单的API,提供手把手教你使用的实例!

    gifmin.js下载地址

    附录

    /**
     * 压缩方法
     * @param {Object} file 需要压缩的GIF文件
     * @param {Number} colors 0~256
     * @param {String} classId  回显div的Id
     * @param {String} uploadId  选择文件input的Id
     */
    function compressGif (file,colors,classId, uploadId) {
        var _file = file;
        console.log(_file)
        if (window.FileReader) {
          var fr = new FileReader();
          fr.readAsArrayBuffer(_file);
          fr.onload = function (e) {
            console.log(fr.result)//fr.result===e.target.result为ArrayBuffer文件
            var result = gifmin(fr.result, colors);
            console.log(result)
            var obj = new Blob([result], {//转化Blob对象
              type: 'application/octet-stream'
            });
            console.log(obj)
            const Blob2ImageFileForWXBrowser = new window.File([obj], _file.name, {//将压缩好的GIF转化成file文件
              type: _file.type
            });
            console.log(Blob2ImageFileForWXBrowser)
            var gifUrl = window.URL.createObjectURL(file); //GIF图片回显用
            // 回显图片
            $('.' + classId).siblings().remove();
            if (classId == 'upload-btn') {
              $('.' + classId).before(`<div class="upload-item upload-item-one" style="display:inline-block;margin-right:5px;">
                      <img id="upload-item-one" src="${gifUrl}" index-video='1'>
                  </div>`);
            }
            uploadImgs.push(Blob2ImageFileForWXBrowser);//添加到上传参数中
            $('#' + uploadId).val('');
            $('#upload-item-one').onload = function () {
              // 如果不生效,请在模态框关闭时销毁
              // 加载完成后销毁url,节省性能
              window.URL.revokeObjectURL(gifUrl);
            }
          }
        }
    }
    

    起源地下载网 » 前端玩转GIF图片压缩

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元