将图片转为canvas,并更换图片选中的颜色

 主要的实现就是将图片中你选中的颜色及其周围相似的颜色更换为你选择好的颜色。

原始图:

结果图:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    canvas {
        border: 1px solid black;
    }
</style>
</head>
<body>
  <canvas id="myCanvas"></canvas>
  <br>
  <label>新颜色: </label>
  <input type="color" id="colorPicker">
  <button id="btn">保存</button>

  <script>
    const btn = document.querySelector('#btn');
    btn.addEventListener('click',e=>{
      const imageURL = cvs.toDataURL('image/png');
      const link = document.createElement('a');
      link.href = imageURL;
      link.download = 'canvas-image.png';
      link.click();
    })
    const cvs = document.querySelector('canvas');
    const ctx = cvs.getContext('2d',{
      willReadFrequently:true,
    });
    const inpColor = document.querySelector('#colorPicker');

    function points2Index(x,y) {
      return (y*cvs.width+x)*4;
    }
    function hex2RGBA(hex) {
      const r = parseInt(hex.slice(1,3),16);
      const g = parseInt(hex.slice(3,5),16);
      const b = parseInt(hex.slice(5,7),16);
      return [r,g,b,255]
    }

    function init(){
      const img = new Image();
      img.crossOrigin = "Anonymous";  // 设置为跨域模式
      img.onload = () =>{
        cvs.width = img.width;
        cvs.height = img.height;
        ctx.drawImage(img,0,0);
      }
      img.src = 'https://inews.gtimg.com/om_bt/OE8piEBa-tbqn-wNvWZl8coi4AlzoUD43upEkoAnIkYL8AA/641';
    }
    init();

    function getColor(x,y,cvsColors) {
      const index = points2Index(x,y);
      return cvsColors.slice(index,index+4);
      
    }

    function diff(color1,color2) {
      return (
        Math.abs(color1[0]-color2[0])+
        Math.abs(color1[1]-color2[1])+
        Math.abs(color1[2]-color2[2])+
        Math.abs(color1[3]-color2[3])
      );
    }

    cvs.addEventListener('click', e =>{
      const clickX = e.offsetX;
      const clickY = e.offsetY;
      const imgData = ctx.getImageData(0,0,cvs.width,cvs.height);// 获取真个画布的颜色RGBA模式
      const cvsColors = imgData.data;
      const hex = inpColor.value;
      const targetColor = hex2RGBA(hex);
      const originColor = getColor(clickX,clickY,cvsColors);
      
      changeColor(clickX,clickY,cvsColors,targetColor,originColor,imgData);
      ctx.putImageData(imgData,0,0);
    })
    function changeColor(x,y,cvsColors,targetColor,originColor,imgData) {
      // if(x<0||x>=cvs.width || y<0||y>=cvs.height){
      //   return;
      // }
      // const curColor = getColor(x,y,cvsColors);
      // if(diff(curColor,targetColor)===0){
      //     return;
      //   }
      //   if(diff(curColor,originColor)>50){
      //     return;
      //   }

      // const index = points2Index(x,y);
      // cvsColors.set(targetColor,index);
      // changeColor(x-1,y,cvsColors,targetColor,originColor);
      // changeColor(x+1,y,cvsColors,targetColor,originColor);
      // changeColor(x,y-1,cvsColors,targetColor,originColor);
      // changeColor(x,y+1,cvsColors,targetColor,originColor);
      const stack = [[x, y]];
      function _changeColor(x,y) {
        const i = points2Index(x,y);
        const color = getColor(x,y,cvsColors);
        if(x<0||x>=cvs.width || y<0||y>=cvs.height){
          return;
        }
        if(diff(color,targetColor)===0){
          return;
        }
        if(diff(color,originColor)>50){
          return;
        }
        cvsColors.set(targetColor,i);
        stack.push([x-1,y],[x+1,y],[x,y-1],[x,y+1]);
      }
      while (stack.length > 0) {
        const [cx, cy] = stack.pop(); // 弹出栈顶元素
        _changeColor(cx, cy); // 处理该点的颜色
      }
      ctx.putImageData(imgData,0,0);
    }
  </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值