前言

网购优惠券 www.fenfaw.cn

最近在博客后台上传图片的时候,突然发现上传gif图片的时候裁剪图片有问题。既没法裁剪gif指定区域的图片,又没法裁剪指定区域生成一个新的指定大小的gif图。本来想直接去找个裁剪的库直接放上去的,但是找了半天也没找到能够裁剪gif然后生成裁剪区域的gif的库,于是就自己动手了。

探索

如果只是单纯的在Gif上裁剪第一帧图片,倒是有插件能实现,我用的就是react-cropper来进行图片裁剪的。但是这个插件没法裁剪GIF生成另一个GIF图。

我要的效果是下面这样的效果

原图

裁剪后的gif图

然后就去查了下如何实现gif图到gif图的裁剪,虽然没有找到对应的插件,但是找到了两个开源的库。

  1. libgif-js 通过解析GIF,生成Canvas
  2. gif.js 把canvas转换成GIF图片

发现这两个功能一组合不就可以实现我要的那个效果了么。

上传GIF => 通过解析GIF每一帧在Canvas上生成对应的图像 => canvas转成GIF

实现

libgif-js的实现过程

libgif-js是通过实现对gif路径发起一个请求,然后通过解析请求回来的gif数据来生成GIF实例(包括每一帧的动画,以及大小之类的基础数据),然后通过GIF实例生成对应的canvas

gif.js的实现过程

通过收集libgif-js转换到canvas上面的每一帧的变化,来生成最终的GIF

gif转换到canvas的实现过程

首先到libgif-js这个项目中下载对应的js文件,因为这个库并没有上传npm,所以需要自己去项目中下载。
libgif-js他这个封装的是对HTML节点的操作,没法直接去用,因为我是上传文件,获取的File对象,所以需要对这个文件进行部分修改

  1. 首先应该接收的是一个url路径,可以把File文件通过URL.createObjectURL(file)转成成url,让其进行XMLHttpRequest请求。 也可以直接传gif的链接。
  2. 然后需要传裁剪的区域范围。裁剪的范围大小需要适配原gif的尺寸比例
  3. 去除libgif-js文件里面不需要的代码,只需要其中每一帧的图像集合跟尺寸大小就行

canvas转换到gif的实现过程

监听gif绘制到canvas上的每一帧变化,然后gif.js收集每一帧的canvas变化,最后生成新的gif

// 导出gif实例, GifToCanvas实例是对libgif-js封装的修改,通过调用init方法,触发gif到canvas的绘制
const gifToCanvas = new GifToCanvas(url, {targetOffset: {dx: cropBoxData.left - canvasData.left,dy: cropBoxData.top - canvasData.top,width: canvasData.width,height: canvasData.height,sWidth: cropBoxData.width,sHeight: cropBoxData.height}
})
// 启动gif转canvas
gifToCanvas.init()// 通过 gif.js 库来收集由 GifToCanvas绘制出来的canvas里面的每一帧,最后生成gif的Blob源。
const gif = new GIF({workers: 2,quality: 10,workerScript: '/static/js/gif.worker.js'
})
const addFrame = (canvas: HTMLCanvasElement, delay: number) => {gif.addFrame(canvas, { copy: true, delay })
}
// 监听每一帧的变化,收集每一帧的变化
gifToCanvas.on('progress', (canvas, delay) => {addFrame(canvas, delay)
})
// 动画执行完毕,执行gif.render
gifToCanvas.on('finished', (canvas, delay) => {addFrame(canvas, delay)gif.render()
})
// canvas生成gif完毕,导出blob, 生成新的文件
gif.on('finished', (blob) => {const newFile = new File([blob], 'new.gif', { type: blob.type })// 上传新的gif文件const formDate = new FormData()formDate.append('file', newFile)...
})

这样就生成了一个裁剪后的gif文件。

参考资源

  • libgif-js
  • gif.js

本项目完整的代码:GitHub 仓库

线上效果演示

博客原文地址

总结

这个项目也没有做太多复杂的设置,满足裁剪GIF的功能就行,因为我目前只需要把gif裁剪成指定大小的gif就行,所以并没有做太多特制化的功能

个人博客源码这个项目也上线了这个功能 | 博客源码项目地址

我自己新创建了一个相互学习的群,无论你是准备入坑的小白,还是半路入行的同学,希望我们能一起分享与交流。
QQ群:810018802, 点击加入

QQ群 公众号
前端打杂群
冬瓜书屋

GIF图片裁剪出指定大小的GIF图片相关推荐

  1. 如何将图片压缩到指定大小?压缩图片大小的方法

    很多报名平台都对图片大小有固定的数值要求,所以不少小伙伴来问,怎么压缩图片200k以下(图片压缩到指定大小 图片压缩大小至指定kb以下-压缩图)?想要把图片压缩指定大小就要用到一些比较专业的工具,今天 ...

  2. python 识别图片中的人脸,并裁人脸,将图片转化成指定大小,并将图片再原文件名保存。

    因工作的原因,每年11月都要处理很多(1000张以上)的照片,并而要把照片处理成一寸大小.因为传统的方式一张一张处理,很费时间,只要是学过计算机都不可能一张一张处理的,之前我都是用软件的批理处理实现的 ...

  3. 前端性能优化:使用媒体查询加载指定大小的背景图片

    日期:2013-7-8  来源:GBin1.com 直到CSS @supports被广泛支持,CSS媒体查询的使用接近于CSS中写逻辑控制.我们经常用CSS媒体查询来根据设备调整CSS属性(通常根据屏 ...

  4. 图片不超过200kb怎么调整?一分钟学会图片压缩到指定大小

    很多网站为了保证页面的流畅度会限制图片上传的kb大小,所以我们需要把图片压缩到指定大小(图片压缩到指定大小 图片压缩大小至指定kb以下-压缩图),那么有没有比较快捷的方法可以自定义压缩图片大小呢?今天 ...

  5. 图片如何缩小到100k?怎么把图片压缩到指定大小?

    有时候在平台上传图片会规定大小100k,图片如何缩小到100k呢?可以使用压缩图的图片压缩到指定大小功能,十分的方便一键操作就可以将图片压缩到100k以内,来看看具体操作步骤吧. 1.打开压缩图点击图 ...

  6. 怎么把图片压缩到30k以内?如何图片压缩到指定大小?

    在公务员考试报名时,需要提交个人证件照片,通常都会要求照片大小不能超过30kb,否则会导致上传失败.那么怎么把图片压缩到30k以内呢?想要把图片压缩到30kb就需要用到压缩图的图片压缩指定大小(图片压 ...

  7. 压缩图片大小的java代码_java按比例压缩图片的源代码,用java如何把图片处理到指定大小...

    [要分析某个网页中的代码构成,需要某个结点下的内容.用此原始方法可以得到整个网页的源码.其实更简单的方法是使用 WebClient 或 HtmlUtil 等开源方式 .public class Ht ...

  8. JS中通过指定大小来压缩图片

    前不久王二写了一个图片处理库,可以指定图片质量压缩图片,调用的是javaScript的原生方法 toDataURL 和 toBlob,库里有如下这些方法: 但是通过质量压缩图片有一些不足之处:无法确定 ...

  9. JS将base64图片压缩至指定大小

    base64图片压缩至指定大小 在开发中,通常在上传图片时,由于各种限制,需要将上传的图片压缩到某一大小范围内才能上传.在此提供以下方法实现该需求,复制可用. /*** 压缩图片到指定大小* @par ...

最新文章

  1. Oracle 11g数据库的部署
  2. 深入理解TCP/IP协议-TCP建立与终止连接
  3. linux 内核编译不能打字,linux系统升级后,手动编译的kernel无法启动问题
  4. java 查询后 jsonobject key 排序_商品品牌业务之后台Java代码的编写
  5. 【Flink】Flink 报错 exited with a non-zero exit code 1
  6. 实用干货!大数据入门的常用技术栈全在这里了
  7. 市级规划课题《小学数学教材解读策略研究》评审书
  8. AB PLC 1769_L24ER_QB1B新机测试固件下载-程序下载
  9. android编程实现128条形码的生成和识别
  10. [1025]python地理处理包shapely
  11. 【Java】maven-shaded-plugin超详细详解
  12. YTU 3166: 共享单车
  13. sqlplus报错ORA-12547: TNS:lost contact解决
  14. ESP32编译运行ADF音频库
  15. 法线变换详解 和 3D 变换中法向量变换矩阵的推导
  16. 十四、Nginx--rewrite规则
  17. 光时域反射仪都有什么功能
  18. mysql logs_MySQL Logs
  19. centos 7 vmstat命令详解
  20. 将url地址中的编码转汉字

热门文章

  1. 浏览器带确定取消的提示框confirm的使用
  2. Solidity基础教程:合约的继承与方法的重写
  3. intel固态硬盘tbw什么意思
  4. python+OpenCv笔记(十七):模板匹配
  5. TikTok美国购物车官宣了,商家怎么申请入驻?
  6. Excel中18位数字如何显示和递增
  7. Elasticsearch笔记五之java操作es
  8. 免费网站mysql模板_十大最常用的PHP+MySql免费CMS模板系统
  9. (简单清晰)为窗口添加背景图片
  10. 类似iphone的短消息效果