狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

canvas實現動態替換人物的背景顏色

freeflydom
2023年11月27日 15:27 本文熱度 590

起因

今天遇見一個特別有意思的小功能。
就是更換人物圖像的背景顏色。大致操作步驟就是:點擊人物-實現背景顏色發生變化

將圖片繪畫到canvas畫布上

我們需要將圖片繪制到canvas畫布上。
這樣做的目的是為了方便我們去操作像素點來更改顏色。
首先創建 Image 的實例。將圖片的地址賦值給圖片實例src。
當圖片加載完成后,onload 事件可以知道圖片是否加載完成
根據 Image的實例將圖片大小賦值給畫布,讓他們大小保持一致。
最后使用 ctx.drawImage來進行繪畫就行
特別提醒的是:src 屬性一定要寫到 onload 的后面,否則程序在 IE 中會出錯。
<body>
  <canvas id="canvas">
 </body>
 <script type="text/javascript">
  // 獲取dom節點
  const  canvas = document.getElementById('canvas')  //獲取上下文
  const ctx = canvas.getContext('2d');  // 將圖片繪制到canvas畫布上
  function initPic(picInfo){    // 創建一個圖片的實例
    const img = new Image()    // 引入圖片的地址
    img.src = picInfo.url 
    img.onload =()=>{      // 設置畫布的寬高與圖片的保持一致
      canvas.width= img.width
      canvas.height= img.height
      // 開始繪畫
      ctx.drawImage(img, 0, 0 );
    }
  }  initPic({    url: './src/assets/person.png'
  }) </script>

drawImage 的簡單介紹

canvas的drawImage()提供了更多在canvas上繪制圖像的方法。drawImage() 方法有三種形式:drawImage(image, dx, dy)  在指定的 (dx, dy) 位置繪制圖像。drawImage(image, dx, dy, width, height)  在指定的 (dx, dy) 位置,并使用指定的寬度和高度繪制圖像。drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, dx, dy, width, height) 在指定的 (dx, dy) 位置,并使用指定的寬度和高度繪制圖像。圖像的源坐標和尺寸也指定了。
image:允許任何的畫布圖像源

注冊事件獲取點擊時的坐標對應的顏色

我們通過 e.offsetX, e.offsetY 可以輕松拿到點擊的坐標x,y。
可以通過 getImageData 獲取到圖片的所有像素點的顏色。
但是怎么通過點擊的位置(x,y)獲取到對應的的像素索引呢?
其實他們的關系是這樣的:// 每個像素占用4個字節(RGBA)const index = (y * image.width + x) * 4; 
根據上面這個公式,我們可以知道坐標對應的像素索引。
有了索引,我們可以拿到坐標對應的顏色
function clickMy(e){  // 獲取點擊時的坐標
  let x = e.offsetX
  let y = e.offsetY
  // 獲取所有的像素點顏色
  let imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);  console.log('獲取所有的像素點顏色', imagedata)  // 這個坐標點對應的顏色
  let clickColor = getColor(x,y, imagedata)  console.log('這個坐標點對應的顏色', clickColor)
}// 計算點擊坐標對應的像素索引 function bgIndex(x,y){  return (y * canvas.width + x) * 4;
}// 根據索引得到顏色值function getColor(x,y,imgData){  let i = bgIndex(x,y)  return [
    imgData.data[i],
    imgData.data[i+1],
    imgData.data[i+2],
    imgData.data[i+3]
  ]
}// 注冊事件canvas.addEventListener("click", clickMy, false)

更改當前像素點的顏色

現在我們希望點擊的這個點的顏色變成紅色。
現在的我們可以拿到所有像素點,當前的坐標,坐標對應的顏色。
現在我們的主角出場了(此時燈光閃爍,五彩的光打在他的身上)
context.putImageData(imageData, x, y);
第1個參數:imageData: 包含了圖像的所有像素數據,
通過ctx.getImageData(0, 0, canvas.width, canvas.height)可以獲取到;
第2,3個參數表示坐標。
它用于將圖像數據繪制到畫布上。
這個方法允許開發者操作和繪制像素級別的數據,
從而實現復雜的圖像效果和處理。
function clickMy(e){  // 獲取點擊時的坐標
  let x =e.offsetX
  let y = e.offsetY
  // 獲取所有的像素點顏色
  let imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);  console.log('獲取所有的像素點顏色', imagedata)  // 這個坐標點對應的顏色
  let clickColor = getColor(x,y, imagedata)  console.log('這個坐標點對應的顏色', clickColor)  // 最后更改為紅色的rgba值
  let targetBgArr = [255,0,0,255]  // 更改顏色
  function changeColor(x,y){    let i = bgIndex(x,y)
    imagedata.data.set(targetBgArr, i)
  }  changeColor(x,y)  // 更改當前像素點的顏色
  ctx.putImageData(imagedata, 0, 0);
}

將被點擊的點的相似顏色全部變為紅色

我們通過兩個顏色的rgba值相減,看rgba的各個絕對值之和。
來判斷顏色的相似。
同時我頁需要注意邊界范圍與顏色已經變為了目標顏色。
這個時候我們就需要停止調用函數了

核心代碼

<!DOCTYPE html><html lang="en"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title></head><body>
  <canvas id="canvas">
 </body>
 <script type="text/javascript">
  // 獲取dom節點
  const  canvas = document.getElementById('canvas')  //  獲取上下文
  const ctx = canvas.getContext('2d',{    willReadFrequently:true
  });  function initPic(picInfo){    // 創建一個圖表的實例
    const img = new Image()
    img.onload =()=>{      // 設置畫布的寬高與圖片的保持一致
      canvas.width= img.width
      canvas.height= img.height
      // 開始繪畫
      ctx.drawImage(img, 0, 0 );
    }    // 引入圖片的地址
    img.src = picInfo.url 
  } 
  function clickMy(e){    // 獲取點擊時的坐標
    let x =e.offsetX
    let y = e.offsetY
    // 獲取所有的像素點顏色
    let imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);    console.log('獲取所有的像素點顏色', imagedata)    // 這個坐標點對應的顏色
    let clickColor = getColor(x,y, imagedata)    console.log('這個坐標點對應的顏色', clickColor)    // 最后更改為紅色的rgba值
    let targetBgArr = [255,0,0,255]    function changeColor(x,y){      // 邊界范圍
      if(x<0 || x>canvas.width || y<0 || y>canvas.height){        return
      }      let color = getColor(x,y,imagedata )      // 相似顏色的相差值
      if(diffBg(color,clickColor)>150){        return
      }      // 已經變為了目標色(紅色)
      if(diffBg(color,targetBgArr)==0){        return
      }      let i = bgIndex(x,y)      // 在內存中更改像素的顏色
      imagedata.data.set(targetBgArr, i)      // 改變周圍(上下左右)的顏色
      changeColor(x+1,y)      changeColor(x-1,y)      changeColor(x,y+1)      changeColor(x,y-1)
    }    changeColor(x,y)    // 將內存中的像素點的顏色(重新繪制在畫布上)
    ctx.putImageData(imagedata, 0, 0);
  }  // 計算點擊坐標對應的像素索引 
  function bgIndex(x,y){    return (y * canvas.width + x) * 4;
  }  
  // 根據索引得到顏色值
  function getColor(x,y,imgData){    let i = bgIndex(x,y)    return [
    imgData.data[i],
    imgData.data[i+1],
    imgData.data[i+2],
    imgData.data[i+3]
    ]
  }  // 查看兩個顏色的相差值
  function diffBg(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]) 
  }  // 注冊事件
  canvas.addEventListener("click", clickMy, false)  initPic({    url: '../assets/person1.png'
  }) </script></html>

更改為按鈕,背景發生改變

上面我們實現了,點擊背景色,實現顏色的更改。
但是實際的過程中。
我們是不知道背景顏色的,怎么去確認背景顏色呢?
其實,可以默認坐標為(4,4)是背景顏色。
在實際的過程中,其實這個位置99.9999%是背景色。
我們是先選擇顏色,然后點擊確定,實現顏色的更改
現在我們來優化一下。讓用戶自己選擇背景色,選擇好后。
點擊確定,背景顏色就發生變化
<!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>
  </style></head><body>
  <div>
    <canvas id="canvas">
  </div>
  <input type="color" id="color" >
  <button id="red">確定</button>
 </body>
 <script type="text/javascript">
  // 獲取dom節點
  const  canvas = document.getElementById('canvas')  //  獲取上下文
  const ctx = canvas.getContext('2d',{    willReadFrequently:true
  });  // 將16進制轉化為rgba的顏色值
  function changeRGBA(hex) {  
    // 去除 # 開頭的第一個字符  
    hex = hex.slice(1);  
    // 將16進制字符串轉換rgba
    let rgba = [];  
    for (let i = 0; i < 6; i += 2) {  
      let byte = parseInt(hex.substr(i, 2), 16);  
      rgba.push(byte);  
    }  
    // 添加 alpha 通道
    rgba.push(255);  
    // 返回 RGBA 顏色值  
    return rgba;  
  }  function initPic(picInfo){    // 創建一個圖表的實例
    const img = new Image()
    img.onload =()=>{      // 設置畫布的寬高與圖片的保持一致
      canvas.width= img.width
      canvas.height= img.height
      // 開始繪畫
      ctx.drawImage(img, 0, 0 );
    }    // 引入圖片的地址
    img.src = picInfo.url 
  } 
  function clickMy(e, type){    let color = document.getElementById('color')    // 4,4的地方默認為是背景顏色
    let x = 4
    let y = 4
    // 獲取所有的像素點顏色
    let imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);    // 這個坐標點對應的顏色
    let clickColor =  getColor(x,y, imagedata)    console.log('這個坐標點對應的顏色', clickColor)    // 顏色為用戶選擇的值
    let targetBgArr = changeRGBA(color.value)    function changeColor(x,y){      // 邊界范圍
      if(x<0 || x>canvas.width || y<0 || y>canvas.height){        return
      }      let color = getColor(x,y,imagedata )      // 相似顏色的相差值
      if(diffBg(color,clickColor)>150){        return
      }      // 已經變為了目標色(紅色)
      if(diffBg(color,targetBgArr)==0){        return
      }      let i = bgIndex(x,y)      // 在內存中更改像素的顏色
      imagedata.data.set(targetBgArr, i)      // 改變周圍(上下左右)的顏色
      changeColor(x+1,y)      changeColor(x-1,y)      changeColor(x,y+1)      changeColor(x,y-1)
    }    changeColor(x,y)    // 將內存中的像素點的顏色(重新繪制在畫布上)
    ctx.putImageData(imagedata, 0, 0);
  }  // 計算點擊坐標對應的像素索引 
  function bgIndex(x,y){    return (y * canvas.width + x) * 4;
  }  // 根據索引得到顏色值
  function getColor(x,y,imgData){    let i = bgIndex(x,y)    return [
    imgData.data[i],
    imgData.data[i+1],
    imgData.data[i+2],
    imgData.data[i+3]
    ]
  }  // 查看兩個顏色的相差值
  function diffBg(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]) 
  }  // 注冊事件
  canvas.addEventListener("click", clickMy, false)
  red.addEventListener("click", clickMy, false)  initPic({    url: '../assets/person1.png'
  }) </script></html>

最后的功能-下載

上面我們已經成功實現讓用戶選擇顏色。
更換用戶自己選擇的顏色。
下載我們只需要實現下載功能就好了。
下載功能主要使用 canvas.toDataURL 然后利用a標簽進行下載
<button id="down">下載</button>
down.addEventListener('click',()=>{  let imgURL = canvas.toDataURL({format: "image/png", quality:1, width:canvas.width, height:canvas.height});  let link = document.createElement('a');
  link.download = "人物圖片";
  link.href = imgURL;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
})



該文章在 2023/11/27 15:27:55 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved