本文作者:IMWeb 孙世吉

未经同意,禁止转载

利用canvas实现一个抠图小工具

0 前言

作为新一代的前端开发工程师,PS抠图切图已经不是必备技能了,我们有UI/交互/视觉等更专业的设计同学帮我们做这个事情。但是有时候还是有一些简单的图片处理工作需要我们去做,例如对图片进行剪裁,调整透明度或者调整图片内的文字等等等。这时候如果有一点PS经验那当然更好,如果没有或者当前的开发环境不一定安装了PS等工具,那我们可能需要去找在线图片处理工具来帮我们完成这些工作。

1 Canvas

老话说得好,一个不想当将军的士兵不是好士兵;一个不想自己写工具的程序猿不是好程序猿。那其实上面提及的一些简单图片处理是可以通过Canvas来帮我们实现的。

canvas是一个可以使用脚本(通常为JavaScript)在其中绘制图形的 HTML 元素。它可以用于制作照片集或者制作简单(也不是那么简单)的动画.。

宋丹丹老师说得好:

要把大象放冰箱,总共分三步:一先把冰箱门打开;二把大象放进去;三把冰箱门带上。

整个Canvas图片处理工具大致也可以分为三步。

1、读取图片资源;

2、把图片资源绘制到画板上;

3、作为前端开发的你可以开始为所欲为了;

先看一下很简单的HTML结构和CSS样式

Canvas图片处理演示

原图:

画布:

点我下载

样式主要是为了增加图片背景文理,用于显示透明度

#input-img {

max-width:400px;

}

#input-upload {

width:200px;

}

/* 图片背景纹理 */

.img-container {

font-size:0;

background-image:-webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #ccc), color-stop(.25, transparent), to(transparent)),-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #ccc), color-stop(.25, transparent), to(transparent)),-webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #ccc)),-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #ccc));

background-size:10px 10px;

}

.err {

border:1px solid red;

}

2 读取图片资源

一般来讲,我们的图片来源有两种。一是设计给你的本地资源;二是线上资源,可以通过URL进行访问的。

// 我们使用两个输入框来引入本地资源和线上资源

const oUpload = document.getElementById('input-upload');

const oInput = document.getElementById('input-url');

// 除此之外还需要一个img标签来加载数据和进行展示

const oImg = document.getElementById('input-img');

// 注: 加载图片的img标签不一定需要放到页面上

基本思路就是利用FileReader读取本地文件,并使用img标签加载数据

oUpload.onchange = loadFile;

oInput.onchange = loadUrl;

// 读取本地文件

function loadFile(e){

const file = e.target.files[0];

const reader = new FileReader();

reader.onload = onFileLoad;

reader.readAsDataURL(file);

}

// 读取输入URL

function loadUrl(e){

oInput.classList.remove('err')

const url = e.target.value;

onFileLoad(url);

}

// 加载图片数据

function onFileLoad(src){

oImg.onload = function(){

onImageLoad(oImg)// 这里使用图像数据,后续讲解

};

oImg.onerror = onImageErr;

oImg.src = (src.target ? src.target.result : src);

}

function onImageErr(){

oInput.classList.add('err');

}

3 canvas 输入输出图像

图像数据有了,那我们就可以开始使用canvas作为载体对图片资源进行处理了。这之前呢我们需要的是从图像到canvas的相互转换,其实就是把图像绘制到画布上,并从画布在上导出图像数据的过程。

这一过程利用了canvas一系列的API先单独拎来说明一下:

canvas - HTML元素

getContext 获得渲染上下文和它的绘画功能

toDataURL 返回一个包含被类型参数规定的图像表现格式的数据链接

context - 通过getContext获取的渲染上下文

drawImage 将图片绘制到画布上

getImageData 获得一个包含画布场景像素数据的ImageData对像

putImageData 像素数据的写入

// canvas实例

const oCanvas = document.getElementById('my-canvas');

// 上面读取资源的操作后,将图像画到canvas上

function onImageLoad(img){

const width = oCanvas.width = img.naturalWidth || img.width;

const height = oCanvas.height = img.naturalHeight || img.height;

const ctx = oCanvas.getContext("2d");

ctx.drawImage(img, 0, 0);

// 获取画布像素信息

const imageData = ctx.getImageData(0, 0, width, height);

// 一个像素点由RGBA四个值组成,data为[R,G,B,A [,R,G,B,A[...]]]组成的一维数组

// 可以通过修改该数组的数据,达到修改图片内容的目的

const data = imageData.data;

filter(data);// 这里对图像数据进行处理

// 把新的内容画进画布里

ctx.putImageData(imageData, 0, 0);

}

// 一个A标签,让用户点击用的

const oDownload = document.getElementById('download');

// 从画布上读取数据并保存到本地

function setDownLoad(fileName){

const url = oCanvas.toDataURL();

oDownload.setAttribute('href', url);

oDownload.setAttribute('target', '_blank');

if (fileName) {

oDownload.setAttribute('download', fileName);

}

}

4 数据处理

以简单的抠图效果为例,那我们实际上要做的事情就是设置像素数据RGBA中的A的值:

function filter(data){

for (let i = 0; i < data.length; i += 4) {

let r = data[i],

g = data[i + 1],

b = data[i + 2];

// 色值在250-256之间都认为是白色

if ([r, g, b].every(v => v < 256 && v > 250)) {

data[i + 3] = 0; // 把白色改成透明的

}

}

}

效果:

上文的实现是将所有的白色替换成透明,同理可以拓展成指定任意颜色范围替换或者调整。

那滤镜效果和选色抠图效果也就都可以很简单的实现出来了~

5 更多与拓展

我们使用PNG图像绝大数场景都是为了保存图像的透明度,但是PNG图片的大小往往差强人意:

PNG采用无损压缩是通过索引色去存储和还原图像的,在存储图像前会先判断图像上哪些地方是相同的哪些地方是不同的,然后对图像上所有出现的颜色进行索引,这些颜色就是索引色。储存的索引色数量越多,文件尺寸越大。8最多只能索引256种颜色,PNG24则可以保存1600多万种颜色,但相应的文件尺寸也会大很多。

我们也可以利用canvas对图片进行压缩,不是说单独的利用canvas的API控制导出图片的质量来进行压缩,虽然说这也是一个思路。而是说

使用 canvas 进行透明度分析,把图片分成透明的 PNG + 不透明的 JPG,然后通过 SVG 将两张图片层叠到一起,减少了不透明部分 alpha 值的储存空间。

基本的流程其实跟上文提到的“大象装冰箱”的过程差不多,在充分利用JPG的压缩率上保留PNG的透明度。基本流程如下:

1、读取图片资源;

2、使用原图像数据去除透明度作为底色画到画板上,这一层可以作为没有透明度的JPG图像,利用JPG图像的压缩效率极大减小图片的存储规模;

3、使用原图像数据将图像颜色数量缩减到一定的数量级(PNG8),并保留透明度,这一层则作为有透明度的PNG图像蒙版盖在上一层图像上,保留图像透明度。

4、将新的图像导出;

这里有一个在线的例子 JPNG.svg

鬼知道一个键盘Z键坏的我是怎么写出这片文章的...

html5 自动扣图,利用canvas实现一个抠图小工具相关推荐

  1. 怎么画图自动生成HTML,用canvas写一个简易画图工具

    本文将为您描述用canvas写一个简易画图工具,具体操作方法: Document style="border:1px solid #000000;">您的浏览器不支持canv ...

  2. html5 自动扣图,html5利用canvas实现颜色容差抠图功能

    利用canvas的getImageData,我们可以获取到一张图片每一个像素的信息,而通过对每一个像素信息的对比,我们就可以找到需要消去的像素点.比如下面这一张图片,如果我们想要扣去白色部分(粉色是b ...

  3. html5 自动扣图,5 秒实现自动抠图?见过 remove.bg 这款神器

    雷锋网(公众号:雷锋网) AI 科技评论按:是否为了简单的抠图功能,还在苦苦修炼 Photoshop 大法?即使修炼成功了,是否觉得在抠图这件事情上花费的时间依然太多?如今一个名叫 remove.bg ...

  4. html5 自动扣图,js+html5 canvas实现ps钢笔抠图

    html5 canvas+js实现ps钢笔抠图 1. 项目要求需要用js实现photoshop中钢笔抠图功能,就用了近三四天的时间去解决它,最终还是基本上把他实现了. 做的过程中走了不少弯路,最终一同 ...

  5. html5 自动扣图,canvas像素点操作之视频绿幕抠图

    本文介绍了canvas像素点操作之视频绿幕抠图,分享给大家,具体如下: 用法: context.putimagedata(imgdata, x, y, dx, dy, dwidth, dheight) ...

  6. html5 自动扣图,Remove.bg – 只需5秒!一键自动抠图移除背景工具 人工智能代替PhotoShop...

    无论是专业的设计师.摄影师还是普通办公者,可能都经历过用 PS 抠图去除背景的苦难日子吧.简单来说,抠图就是将照片的主体人或物品从图片中抠出来,以便贴到别处使用. 然而抠图虽然是 PhotoShop ...

  7. 如何利用canvas画一个圆,并且填充颜色

    如何利用canvas画一个圆,并且填充颜色(小白专用,大佬勿看) canvas基础 相信在此之前,你对canvas已经有一定的了解了,接下来我将介绍,如何利用canvas画一个圆. 1.新建一个htm ...

  8. python数据预测_利用Python编写一个数据预测工具

    利用Python编写一个数据预测工具 发布时间:2020-11-07 17:12:20 来源:亿速云 阅读:96 这篇文章运用简单易懂的例子给大家介绍利用Python编写一个数据预测工具,内容非常详细 ...

  9. android打地鼠设计报告,android开发中利用handler制作一个打地鼠小游戏

    android开发中利用handler制作一个打地鼠小游戏 发布时间:2020-11-25 15:21:11 来源:亿速云 阅读:136 作者:Leah 这期内容当中小编将会给大家带来有关androi ...

最新文章

  1. 学习,是前进的必由之路
  2. leetcode 在排序数组中查找元素的第一个和最后一个位置
  3. JVM垃圾回收算法 总结及汇总
  4. 改进同步等待的网络服务端应用 (转)
  5. Java函数式编程和面向对象编程
  6. 学术谱系树:来看看你导师的师承
  7. 为什么不用小驼峰也能查到数据库数据_为什么不用驼峰命名创建表名和字段?...
  8. java语言的数据类型_Java语言的数据类型
  9. Gephi教程:使用Graph Streaming 插件实现数据可视化
  10. 读《About Face 4 交互设计精髓》16
  11. ie7/8卸载工具 降级到IE6
  12. python Pytesseract 动态验证码图片识别
  13. c语言输出99乘法表的思路,C语言输出99乘法表
  14. 这样的文件操作有点玄——文件流学习 ( 二 )
  15. 应用服务器和数据库服务器有什么区别?
  16. 全国 省市区 经纬度 (XML格式)
  17. 【面试题】MyBatis面试题
  18. 熵、条件熵、联合熵、互信息的理解
  19. Mac干货 如何快速的在Mac上安装Windows双系统?虚拟机Parallels Desktop +Bootcamp安装
  20. Grammarly使用说明

热门文章

  1. 字符串函数的介绍带模拟_strcpy
  2. idea设置文件过滤
  3. 如何在 iPhone 和 iPad 上关闭自动更正?
  4. TypeScript从入门到项目实战(进阶篇)
  5. 原子制造:物质科学的未来技术
  6. Media Encoder 2020 for Mac(me 2020 大师版)
  7. google guava 入门教程
  8. vue项目使用IE浏览器运行报错
  9. 中国黄金协会:中国黄金消费连续6年全球居首
  10. 动态NAT配置实验(1)