前言

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

奉天承运,公司诏曰:介于前端组表现优异,后端组忙里偷不出闲,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权限。

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 对象。

语法

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 = urlimg.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);

附注

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图片压缩

准备

查阅资料

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

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

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

思考分析

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

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

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

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

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

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

得出结论

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

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

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

实践

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

原图:

可以看到原图大小1823814b

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

减帧压缩后:

可以看到减帧压缩后大小为1617818b

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

减帧减色压缩后:(极限值只有黑白2种颜色)

//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图片压缩上传相关推荐

  1. 前端图片压缩上传(纯js的质量压缩,非长宽压缩)

    前端图片压缩上传(纯js的质量压缩,非长宽压缩) 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下: <!DOCTYPE html> ...

  2. web 前端图片优化之--图片压缩上传

    移动前端-图片压缩上传实践  此前有同事跟我聊过关于移动端用canvas压缩图片后再上传的功能,最近有了点空闲时间,所以就实践了一下.demo效果链接在文章底部贴出. 在做移动端图片上传的时候,用户传 ...

  3. JS前端图片压缩上传

    JS前端图片压缩上传重点知识 最近在做一个手机端的图片上传,写了一个比较符合自己要求的方法,可供参考 在做这个功能模块时,我遇到了以下问题,都花费了大量时间: 1. 不知道怎么压缩图片,(代码和方法) ...

  4. 前端图片压缩上传(压缩篇)

    为什么说这是一篇比较适合小白的前端图片压缩文章呢?因为我也是一个刚工作半年的前端小白,最近接到了一个前端图片压缩上传的任务,通过各种百度博客完成了这项任务,但是任务完成后对各种技术细节却还不是特别理解 ...

  5. 基于Plupload的图片压缩上传

    前言 这里的上传工具基于JQuery.Plupload 传送门:Plupload官方.中文文档 为什么要做图片压缩? 现在手机拍照都快10M了,但是有时候图片上传只要看得清楚就可以了,比如上传身份证2 ...

  6. 移动端实现图片压缩上传

    移动端实现图片压缩上传 目前来说,HTML5的各种新API都在移动端的webkit上得到了较好的实现.根据查看caniuse,本demo里使用到的FileReader.Blob.Formdata对象均 ...

  7. 基于vue + axios + lrz.js 微信端图片压缩上传

    业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...

  8. [html] 如何使用html5进行图片压缩上传?

    [html] 如何使用html5进行图片压缩上传? 1.获取到图片的base64格式: 2.图片加载完成后,把图片转化为canvas: 3.使用canvas的toDataURL按照自己的需要进行压缩: ...

  9. js 图片压缩上传(base64位)以及上传类型分类

    一.input file上传类型 1.指明只需要图片 <input type="file" accept='image/*'> 2.指明需要多张图片 <input ...

最新文章

  1. redis 突然大量逐出导致读写请求block
  2. final 修饰方法参数
  3. 【ZOJ - 3778】Talented Chef(贪心)
  4. db2 mysql sql server_连接数据库的方法(Oracle DB2 SQL Server MySQL...)
  5. UI基础控件创建(UILabel、UITextField、UIButton)
  6. xcode 中不小心删除 stroryboard 的恢复办法
  7. KNN(一)--简单KNN原理及实现
  8. BT5无法启动图形界面问题
  9. 快手测试开发工程师面试
  10. 导出包含富文本内容和图片的word和pdf
  11. DCOS搭建zookeeper集群搭建
  12. ClientJS是什么?
  13. krnln.fnr和shell.fne_电脑开机显示failedtoloadkernllibrary什么意思啊
  14. svn服务端的安装及其启动
  15. oracle找不到 dba_tables,不经意发现的dba_objects和dba_tables中的细节
  16. Ubuntu16.04安装Nvidia显卡驱动(cuda)
  17. 递推递归练习H - 三国佚事——巴蜀之危
  18. ajax请求 拦截窗口,ajax请求成功后新开窗口window.open()被拦截解决方法
  19. 离散数学-一阶逻辑等值式与置换规则
  20. Apache 配置虚拟主机三种方式

热门文章

  1. [高通SDM450][Android9.0]CTA认证--去掉录音功能
  2. yii 高级版后台清理前台的缓存
  3. 解决 eclipse 上 Keystore was tampered with, or password was incorrect
  4. 神经网络实现猫的种类识别
  5. 布局练习——网易新闻
  6. python列表逆序
  7. nginx配置多个一级域名https访问的配置
  8. Python爬虫实战 | 利用多线程爬取 LOL 高清壁纸
  9. 每日一题 | 数学神童的红眼睛与蓝眼睛问题
  10. 什么软件可以支持视频转换成文字?