基于 vue.js 实现图片本地预览 + 裁剪 + 压缩 + 上传的功能(二)

这一篇要说说裁剪、压缩,这两个功能都要用到 canvas 的能力,canvas 在 IE9 以上浏览器都支持良好,也为 IE9 提供为数很少的能够进行文件操做的 API。javascript

基础代码

<div id='box'></div>
const canvas = document.getElementById('box')
const ctx = canvas.getContext('2d')

如何给 canvas 导入图片

经过实例方法 drawImage 能够在canvas 中绘制图片。html

drawImage 接受的第一个参数描述以下:java

An element to draw into the context. The specification permits any canvas image source (CanvasImageSource), such as an HTMLImageElement, an HTMLVideoElement, an HTMLCanvasElement or an ImageBitmap.

可是 IE9 中没法传入一个加载了图片的 IMG 元素。git

换种思路,在 IE9 中作如下兼容处理:github

先把图片上传,而后加载远程图片进行处理,可是碰到一些问题:canvas

  • 若是本地图片过大,上传并下载耗时严重
  • canvas 因为安全问题没法加载跨域图片,致使上传 CDN 的方案没法使用

或者直接上到 CDN (咱们用的是七牛),并把上传后的 key 以及裁剪参数传给后台,经过后台调用七牛的裁剪服务和持久化服务,可是问题又来了:跨域

  • 增长了后台服务的依赖,增长了请求数
  • 因为七牛在持久化时,须要排队处理,不保证能实时预览
  • 定时去轮询新的图片地址,常常须要耗时很长,而且有可能生成失败
  • 即便经过临时展现剪裁服务返回回来的地址,也常常会出现持久化服务调用失败的问题,失败缘由信息不多,调试很麻烦。

总的来讲,这些方案性价比不高!浏览器

如何作裁剪

两种思路:安全

  1. 经过 CSS + JS 模拟能够获取 裁剪长宽 以及 裁剪起始位置,而后将参数输出给 canvas
  2. 直接在 canvas 里面操做

最后,都经过实例方法 drawImage 来进行裁剪。ide

如何压缩

github上有一个国人用 javascript 写的无依赖的本地压缩库 localResizeIMG3

也能够继续用 canvas 的实例方法 toDataURL 简单实现

打脸的事情要开始了

利用 flash 制做了一个swf 文件,在 IE9 中选择图片、读取图片,并输出 base64 格式。

原本想把本地图片地址传给 swf 文件,让它直接读路径,可是因为安全问题,会被阻止,因此还得经过 flash 来选择图片

虽然被打脸,说几个好处:

  • 能够统一加载 base64 格式的图片,图片预览,获取图片长宽,都不用单独处理 IE9
  • 若是须要,能够扩展一个读取图片大小的功能
  • 上传图片,能够直接用 xmlhttprequest 上传 Base64 格式的图片(这里用到的七牛 CDN 提供的上传 Base64 图片服务),不用后台配合搞 iframe 上传方案,或者加载第三方上传插件,经过 flash 上传

实现代码参考:https://github.com/yannickcr/...

现实是残酷的,七牛 CDN 上确实能找到一个古老的上传 base64 格式图片的服务,可是因为服务是跨域的,而且要求在请求头里面携带参数,所以 IE9 中是没法经过 Javascript 实现上传。

总结

  • 若是支持 IE9 及如下浏览器,建议本地模拟裁剪,把裁剪参数和原图传给后台,剩下的都交给后台处理
  • 若是支持 IE10 等高级浏览器,建议使用本地方案,把裁剪压缩后的图片传到 CDN。

参考

相关文章
相关标签/搜索