iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >html5如何利用canvas实现颜色容差抠图功能
  • 778
分享到

html5如何利用canvas实现颜色容差抠图功能

2023-06-09 11:06:05 778人浏览 薄情痞子
摘要

这篇文章主要介绍了HTML5如何利用canvas实现颜色容差抠图功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。利用canvas的getImageData,我们可以获取到一

这篇文章主要介绍了HTML5如何利用canvas实现颜色容差抠图功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

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

html5如何利用canvas实现颜色容差抠图功能 

let canvas = document.querySelector('#canvas');let context = canvas.getContext('2d');let img = document.createElement('img');img.src = './head2.png';img.onload = function () {    canvas.height = img.height;    canvas.width = img.width;    context.drawImage(img, 0, 0);    cutout(canvas, [255, 255, 255], 0.2); // 对白色进行抠除,容差为0.2}function cutout(canvas, color, range = 0) {    let context = canvas.getContext('2d');    let imageInfo = context.getImageData(0, 0, canvas.width, canvas.height);    // pixiArr是一个数组,每四个数组元素代表一个像素点,这四个数组元素分别对应一个像素的r,g,b,a值。    let pixiArr = imageInfo.data;    for (let i = 0; i < pixiArr.length; i += 4) {    // 匹配到目标像素就将目标像素的alpha设为0        if (testColor([pixiArr[i], pixiArr[i + 1], pixiArr[i + 2]], color, range)) pixiArr[i + 3] = 0;    }    context.putImageData(imageInfo, 0, 0);}function testColor(current, target, range) {    for (let i = 0; i < 3; i++) {        if (!((1 - range) * target[i] <= current[i] && (1 + range) * target[i] >= current[i])) return false;    }    return true;}

testColor(current, target, range) 方法三个参数分别为 待检测像素点的rgb数组 、 目标像素点的rgb数组 和 容差范围 ,这里的容差只是简单用r、g、b的值分别乘以(1 + range)和(1 - range)来计算并对比,不同的容差参数会得到不同的效果&darr;

range = 0.095

html5如何利用canvas实现颜色容差抠图功能 

range = 0.1

html5如何利用canvas实现颜色容差抠图功能 

range = 0.2

html5如何利用canvas实现颜色容差抠图功能 

当然对于底色是标准的纯色的图片就不需要容差了。

边界处理

但是有时候我们希望有一个边界,让抠图操作不对边界内部的像素造成影响。比如上面的图片,我们希望不会对人物头像内部的像素造成影响。 如果我们一行一行来看,是不是只要在碰到不是边界像素的时候停止操作,就可以达到效果了呢?

我们对每一行分别进行扫描,定义一个左指针 left 指向这一行的第一个像素,定义一个右指针 right 指向这一行的最后一个像素,并用一个 leftF 标识左边是否碰到边界,一个 rightF 标识右边是否碰到边界,当没碰到边界时指针就一直向内收缩,直到两个指针都碰到边界或者左右指针重合就跳到下一行,直到所有行都扫描完毕。

function cutout(canvas, color, range = 0) {    let context = canvas.getContext('2d');    let imageInfo = context.getImageData(0, 0, canvas.width, canvas.height);    let pixiArr = imageInfo.data;    for (let row = 0; row < canvas.height; row++) {        let left = row * 4 * canvas.width; // 指向行首像素        let right = left + 4 * canvas.width - 1 - 3; // 指向行尾像素        let leftF = false; // 左指针是否碰到边界的标识        let rightF = false; // 右指针是否碰到边界的标识        while (!leftF || !rightF) { // 当左右指针都为true,即都碰到边界时结束            if (!leftF) {                if (testColor([pixiArr[left], pixiArr[left + 1], pixiArr[left + 2]], color, range)) {                    pixiArr[left + 3] = 0; // 此像素的alpha设为0                    left += 4; // 移到下一个像素                } else leftF = true; // 碰到边界            }            if (!rightF) {                if (testColor([pixiArr[right], pixiArr[right + 1], pixiArr[right + 2]], color, range)) {                    pixiArr[right + 3] = 0;                    right -= 4;                } else rightF = true;            }            if (left == right) { // 左右指针重合                leftF = true;                rightF = true;            };        }    }    context.putImageData(imageInfo, 0, 0);}

html5如何利用canvas实现颜色容差抠图功能 

虽然大概完成了我们的需求,但是看一下上面头发那为啥会多了一块白色

html5如何利用canvas实现颜色容差抠图功能 

因为我们仅仅只进行了行扫描,当左指针碰到头发时就会停止扫描,但是头发弧度里面的就无法被扫描到了,我们还需要进行列扫描,改造一下上面的方法:

function cutout(canvas, color, range = 0) {    let context = canvas.getContext('2d');    let imageInfo = context.getImageData(0, 0, canvas.width, canvas.height);    let pixiArr = imageInfo.data;    for (let row = 0; row < canvas.height; row++) {        let left = row * 4 * canvas.width;        let right = left + 4 * canvas.width - 1 - 3;        let leftF = false;        let rightF = false;        while (!leftF || !rightF) {            if (!leftF) {                if (testColor([pixiArr[left], pixiArr[left + 1], pixiArr[left + 2]], color, range)) {                    pixiArr[left + 3] = 0;                    left += 4;                } else leftF = true;            }            if (!rightF) {                if (testColor([pixiArr[right], pixiArr[right + 1], pixiArr[right + 2]], color, range)) {                    pixiArr[right + 3] = 0;                    right -= 4;                } else rightF = true;            }            if (left == right) {                leftF = true;                rightF = true;            };        }    }    // 同理进行列扫描    for (let col = 0; col < canvas.width; col++) {        let top = col * 4; // 指向列头        let bottom = top + (canvas.height - 2) * canvas.width * 4 + canvas.width * 4; // 指向列尾        let topF = false;        let bottomF = false;        while (!topF || !bottomF) {            if (!topF) {                if (testColor([pixiArr[top], pixiArr[top + 1], pixiArr[top + 2]], color, range)) {                    pixiArr[top + 3] = 0;                    top += canvas.width * 4;                } else topF = true;            }            if (!bottomF) {                if (testColor([pixiArr[bottom], pixiArr[bottom + 1], pixiArr[bottom + 2]], color, range)) {                    pixiArr[bottom + 3] = 0;                    bottom -= canvas.width * 4;                } else bottomF = true;            }            if (top == bottom) {                topF = true;                bottomF = true;            };        }    }    context.putImageData(imageInfo, 0, 0);}

至于top和bottom为啥是那样计算画个矩阵图大概就知道了。

html5如何利用canvas实现颜色容差抠图功能 

处理后&darr;

html5如何利用canvas实现颜色容差抠图功能 

其实还可以先将 pixiArr 包装为以一个像素点为单位的矩阵

[    [{r: 255, g: 255, b: 255, a: 1}, {r: 255, g: 255, b: 255, a: 1}, {r: 255, g: 255, b: 255, a: 1}],    [{r: 255, g: 255, b: 255, a: 1}, {r: 255, g: 255, b: 255, a: 1}, {r: 255, g: 255, b: 255, a: 1}]    [{r: 255, g: 255, b: 255, a: 1}, {r: 255, g: 255, b: 255, a: 1}, {r: 255, g: 255, b: 255, a: 1}]]

处理后计算像素下标也就会更简单,列扫描时直接先将这个矩阵旋转,再用行扫描处理一遍就行了。这样处理pixiArr也有利于进一步对算法进行优化

上述方法虽然大概完成了抠图效果,但是这种简单处理还会有许多情况没有考虑到。

比如右边头发这里是行扫描和列扫描都无法触碰到的区域&darr;

html5如何利用canvas实现颜色容差抠图功能 

下面的衣服也因为颜色和底色一样且没有边界在列扫描中被直接抹去了&darr;

html5如何利用canvas实现颜色容差抠图功能 

最后

对于主体和底色区分度很大的图片来说,最开始的那种方法就已经够用了。这篇中我采用的容差和边界处理算法的优化空间还很大,但是它们是非常容易实现与理解的,这篇权当做一个引子,各位完全可以根据自己的能力继续去实现边界与容差算法。

感谢你能够认真阅读完这篇文章,希望小编分享的“html5如何利用canvas实现颜色容差抠图功能”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

--结束END--

本文标题: html5如何利用canvas实现颜色容差抠图功能

本文链接: https://www.lsjlt.com/news/255883.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • html5如何利用canvas实现颜色容差抠图功能
    这篇文章主要介绍了html5如何利用canvas实现颜色容差抠图功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。利用canvas的getImageData,我们可以获取到一...
    99+
    2023-06-09
  • HTML5 Canvas如何实现颜色填充
    这篇文章主要为大家展示了“HTML5 Canvas如何实现颜色填充”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML5 Canvas如何实现颜色填充”这篇文...
    99+
    2024-04-02
  • 如何使用HTML5 Canvas实现图片缩放、颜色渐变效果
    这篇文章主要为大家展示了“如何使用HTML5 Canvas实现图片缩放、颜色渐变效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用HTML5 Canva...
    99+
    2024-04-02
  • 如何利用canvas实现图片压缩功能
    小编给大家分享一下如何利用canvas实现图片压缩功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!项目中做身份证识别时,需要传送图片的 base64 格式编码,...
    99+
    2023-06-09
  • canvas与html5如何实现视频截图功能
    这篇文章主要介绍了canvas与html5如何实现视频截图功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。制作方法:1.在页面中加载视频在...
    99+
    2024-04-02
  • OpenCV如何使用GrabCut实现抠图功能
    这篇文章主要介绍“OpenCV如何使用GrabCut实现抠图功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“OpenCV如何使用GrabCut实现抠图功能”文章能帮助大家解决问题。1、概述案例:使...
    99+
    2023-07-05
  • 如何使用HTML5 Canvas为图片填充颜色和纹理
    这篇文章将为大家详细讲解有关如何使用HTML5 Canvas为图片填充颜色和纹理,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。填充颜色艺术离不开色彩,今天咱...
    99+
    2024-04-02
  • 如何利用canvas实现图片下载功能来实现浏览器兼容问题
    小编给大家分享一下如何利用canvas实现图片下载功能来实现浏览器兼容问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言:项目中需要实现图片下载功能,第一个想...
    99+
    2023-06-09
  • HTML5如何使用Canvas实现放入图片和保存为图片功能
    这篇文章给大家分享的是有关HTML5如何使用Canvas实现放入图片和保存为图片功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。使用JavaScript将图片拷贝进画布要想将图...
    99+
    2024-04-02
  • 怎么在html5中利用canvas实现一个弹幕功能
    本篇文章为大家展示了怎么在html5中利用canvas实现一个弹幕功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。(function () {   ...
    99+
    2023-06-09
  • C++ opencv如何利用grabCut算法实现抠图
    今天小编给大家分享一下C++ opencv如何利用grabCut算法实现抠图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2023-06-30
  • 基于Html5 canvas如何实现裁剪图片和马赛克功能
    这篇文章主要介绍了基于Html5 canvas如何实现裁剪图片和马赛克功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.核心功能  此组件功能包含:    图片裁剪(裁剪...
    99+
    2023-06-09
  • canvas绘图中如何实现撤销功能
    这篇文章给大家分享的是有关canvas绘图中如何实现撤销功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。最近在做网页版图片处理相关的项目,也算是初入了 canvas 的坑。项目需求中有一个给图片添加水印的功能。...
    99+
    2023-06-09
  • 如何利用一行python代码实现灰度图抠图
    这篇“如何利用一行python代码实现灰度图抠图”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何利用一行python代码实...
    99+
    2023-06-30
  • 如何通过Python调用接口实现抠图并改底色
    这篇文章主要介绍了如何通过Python调用接口实现抠图并改底色的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何通过Python调用接口实现抠图并改底色文章都会有所收获,下面我们一起来看看吧。一、注册百度AI账...
    99+
    2023-07-04
  • 如何在python中使用opencv实现一个颜色检测功能
    本文章向大家介绍如何在python中使用opencv实现一个颜色检测功能的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络...
    99+
    2023-06-06
  • 如何将HTML5 Canvas的内容保存为图片借助toDataURL实现
    本篇文章给大家分享的是有关如何将HTML5 Canvas的内容保存为图片借助toDataURL实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧...
    99+
    2024-04-02
  • 如何使用HTML5实现多张图片上传功能
    小编给大家分享一下如何使用HTML5实现多张图片上传功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! HTML结构: &l...
    99+
    2024-04-02
  • 利用java怎么实现一个将图片去色的功能
    本篇文章为大家展示了利用java怎么实现一个将图片去色的功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。现在我们要将这样的一张图片变成为代码package com.epoint.wdg.test;...
    99+
    2023-05-31
    java ava
  • Html5 中怎么利用FileReader实现即时上传图片功能
    Html5 中怎么利用FileReader实现即时上传图片功能,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。<!DOCT...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作