前端图像处理指南

计算机图像处理是一门很成熟的技术,任何一门可操做系统接口的语言都能很轻易的实现各类处理操做。可是前端限于浏览器环境和接口限制,处理起来会有诸多不便,这里所说的前端图像处理,是真的指不借助任何后端服务纯前端实现的图像处理。本文会介绍canvas位图处理,SVG矢量图和CSS3图像处理,重点是canvas,而且最后会附上一个TrimPNG小应用javascript

canvas位图处理

HTML5 canvas为咱们提供了一块画布,让前端也有了操做位图的功能:图片旋转、缩放、滤镜、压缩等均可以经过JS来实现。css

图像基本处理

经过设置drawImage参数能够实现图片绘制、缩放、拉伸和裁剪等操做(注意canvas没法绘制体积过大图片,不然会卡甚至崩掉,大图能够分块读取绘制):html

图片描述
图片描述

详细用法参考 drawImage(),DEMO源码戳这里 JS Bin. 前端

只须要drawImage一个方法,就能够实现基本图形处理功能,再结合鼠标或滚轮事件,就能够实现更复杂的局部放大预览,缩放等功能了。java

图像滤镜处理

如今的朋友圈发个图都要用滤镜美一下,复古清纯胶片LOMO各类风格应有尽有。canvas提供了getImageData方法来获取图像上每个像素点的RGBA信息,这样咱们就能对图片进行像素级处理了。经过特定算法来重写imageData中的像素信息,而后用setImageData方法把新的数据从新绘制在canvas上,这样就能够实现图像滤镜打码加特效等一系列功能。git

好比咱们如今要实现一个复古滤镜:程序员

// 复古滤镜处理算法:获取每一个像素的RGB信息,并按特定权重返回其加权平均值
let sepiaFilter = function(imgData) {
  let d = imgData.data
  for (let i = 0; i < d.length; i += 4) {
    let r = d[i]
    let g = d[i + 1]
    let b = d[i + 2]
    d[i] = (r * 0.393) + (g * 0.769) + (b * 0.189) // red
    d[i + 1] = (r * 0.349) + (g * 0.686) + (b * 0.168) // green
    d[i + 2] = (r * 0.272) + (g * 0.534) + (b * 0.131) // blue
  }
  return imgData
}
//图像地址必须和当前页面同域,不然会报cross-origin错误 
img.src = '/img/logo@2x.png' 
img.onload = () => {
  ctx.drawImage(img, 0, 0) // 绘制原图
  let imgData = ctx.getImageData(0, 0, img.width, img.height) // 获取图片信息
  ctx.putImageData(sepiaFilter(imgData), 100, 0) // 绘制处理后图片
}复制代码

图片描述
图片描述

详细用法参考 getImageData()putImageData(),DEMO源码戳这里 JSFiddle.github

滤镜处理关键在于滤镜算法,要想写出更高级的特效须要有计算机图形学基础,对卷积矩阵、拉普拉斯变换、傅里叶变换等数学知识也要了解,这个坑很大我就不挖了。web

图像base64存储

加完特效后若是咱们想把图像保存下来,就能够用toDataURL方法来对图片进行格式转换、压缩存储了。算法

// 支持三种文件类型:image/png(默认) | image/jpeg | image/webp(仅Chrome)
canvas.toDataURL() // 默认存储为png
// 仅jpeg/webp支持质量参数(0~1,默认0.92)
canvas.toDataURL("image/jpeg", 0.1) // 存储为质量为0.1的jpeg复制代码

因为存储形式是base64编码,原来图片的每三个字节都会被扩展成4字节,因此总体上编码后数据会比原来多约1/3。如下是经过toDataURL存储后的图片和原图大小相关对比数据(数据仅供参考,不具通用性):

图片描述
图片描述

可见存储后图片体积并非原来的4/3,实际上处理后的图片都会比原图大好几倍,而且不一样的图片增大的体积也是不肯定的。若是是要上传图片到服务器,能够把base64转化成Blob二进制数据压缩上传;若是要直接在前端显示或供用户下载,jpg还好能够设置质量参数,要是png就无法压缩了。

只是用toDataURL还不够,用户须要经过手动点击图片-右键图片存储为来保存图片,若是要实现点击下载按钮自动下载图片还须要修改图片类型为octet-stream,而后利用HTML5的download属性强制让浏览器下载。

详细用法参考toDataURL(). 自动下载图片DEMO源码快戳我 JSFiddle.

程序员的备胎

有了以上基础,再结合成熟的图形处理算法,咱们能够完成平常工做中大部分图像处理需求,如下列出了一些相关轮子可作备胎。备胎这种东西多多益善,万一之后用到了呢?

注意:本人很专注。

html2canvas

将web页面经过canvas来实现截屏,其原理就是遍历DOM结构和样式,而后在canvas中绘制出来,经过toDataURL输出图片。但因为canvas图片的同源策略限制,若是图片和网站不一样源的话会截取不出来的。另外在微信中测试时,即便用同源的图片截取出来的图片也有问题,因此要想将其用于生产环境,仍是得看场景,有不少坑要踩。

code-to-image

代码转图片工具。有时候你在不一样的平台写文章贴代码,因为不一样平台代码格式化规范不一,因此常常会出现代码排版问题,经过这个工具将代码转成图片就能够避免排版问题了。

Cropper

一个专门用来作图片裁剪的应用。

tracking.js

这是一个专业的计算机视觉处理JS库,包含了大量图形处理算法,可用来作人脸识别,色彩追踪等酷炫功能。

qrcode2

用JS动态生成二维码,这个库仍是很实用的,原理就是qrcode算法+canvas绘图,不支持canvas的用table兼容。

AlloyImage

腾讯出的基于HTML5的专业级图像处理开源引擎,功能很强大,简直就是Web版的PS。

以上列举部分,更多备胎在此: github.com/0326/canvas

SVG矢量图处理

讲完位图再说矢量图。矢量图在绘制图标、商业LOGO、动画元素上应用很是广范。Web最开始支持的矢量图形并非如今的SVG,而是微软主推的VML,因此在低版本IE下面只支持VML而不支持SVG,直到后来SVG成为W3C标准并被普及,微软才在IE9中支持SVG。

SVG遵循XML规范,能够很好的集成在HTML里面,同时支持JS脚本控制,还有基于SMIL标准的动态内容支持,作起动画来也是很是方便。目前基于SVG的JS图形库轮子也是很是多,如svg.js, Snap.svg, Velocity.js, D3.js等等,目前暂无SVG应用需求,等用的时候再翻牌子吧。

CSS图像处理

若是你的图像特效只是用来给用户展现,并不须要存储的话,能够直接用CSS处理,基本的调整图片大小、拉伸、旋转、裁切等操做直接几个CSS属性width/height/skew/rotate/clip-path等就能搞定了。若是想加特效,使用CSS滤镜Duang的一下就出来了,不须要任何图形学基础和数学知识:

详细说明见 CSS filter - MDN, DEMO 源码见JS Bin.

总结

最后介绍个小工具TrimPNG。你们都知道TinyPNG能够压缩PNG, TrimPNG顾名思义就是去除图片空白和白边的,实现了自动抠图和切图的功能(logo我是直接抄的TinyPNG,都是熊猫,应该没关系😝)

图片描述
图片描述

用到的技术点上面都说到了,裁切实现原理就是横向纵向分别扫描两次像素点阵,找出上下左右最外面的非透明点,而后定位出有效图像区域。去除白边算法目前还比较傻逼,只要是接近白色的点都被我干掉了,后面再完善好了 去白边算法优化了一下,采用标记清除策略,先扫描一遍标记出可疑白点,而后再扫描一遍,凡是与透明区域相邻的可疑白点就清除,固然这个算法也比较死,若是有更专业更智能的请务必告诉我。

体验地址:quanfeng.tech/trimpng/

本文只抛砖,做为工做时技能储备,若有任何补充欢迎留言交流:)

相关文章
相关标签/搜索