摘要:當(dāng)然實(shí)現(xiàn)算法還不是很完善,主要是為了給大家展示的無限可能,當(dāng)然我也在逐步優(yōu)化算法中,使得圖片摳圖更加完美,更加智能,也歡迎大家的
最近在研究html5 canvas的過程中,發(fā)現(xiàn),canvas為前端對(duì)圖像的處理開辟了一條新的道路,canvas可以做到很多事情,甚至可以做個(gè)類似于PhotoShop的東西,曾經(jīng)本人在一家軟件工作就做類似的工作,可以看一下我之前開發(fā)的軟件:
這個(gè)就是canvas實(shí)現(xiàn)的類似于Adobe Photoshop,足以見得canvas的強(qiáng)大之處!
本文就是抽出其中一個(gè)小的功能點(diǎn),來簡(jiǎn)單聊聊canvas強(qiáng)大之處:我們來一步步實(shí)現(xiàn)一個(gè)簡(jiǎn)單的智能摳圖功能:(具體的代碼見我的github:monkeyWangs/Matting)
1.環(huán)境準(zhǔn)備
本人采用ES6語(yǔ)法作為開發(fā)環(huán)境,選用webpack作為構(gòu)建工具,于是乎,我們有了webpack.config.js
/** * @author monkeyWang * */ /* 引入操作路徑模塊和webpack */ var path = require("path"); var webpack = require("webpack"); module.exports = { /* 輸入文件 */ entry: "./src/index.js", output: { /* 輸出目錄,沒有則新建 */ path: path.resolve(__dirname, "./dist"), /* 靜態(tài)目錄,可以直接從這里取文件 */ publicPath: "/dist/", /* 文件名 */ filename: "matting.js" }, module: { rules: [ /* 用babel來解析js文件并把es6的語(yǔ)法轉(zhuǎn)換成瀏覽器認(rèn)識(shí)的語(yǔ)法 */ { test: /.js$/, loader: "babel-loader", /* 排除模塊安裝目錄的文件 */ exclude: /node_modules/ } ] } }
這樣變準(zhǔn)備好了開發(fā)用的基本環(huán)境,接下來我們來實(shí)現(xiàn)具體的核心代碼,為了方便起見,我的代碼全寫在了inde.js
2.代碼實(shí)現(xiàn)
首選我們需要新建一個(gè)對(duì)象:
/** * @author monkeywang * Date: 17/3/30 */ class Matting { }
然后我們需要接受用戶上傳的圖片文件:
class Matting { /** * 構(gòu)造函數(shù) * @param file */ constructor(file) { this.file = file } }
再接著把圖片文件轉(zhuǎn)成base64格式,所以我們?cè)陬愔薪艘粋€(gè)createStream方法:
createStream() { let reader = new FileReader() let ext = this.file.name.substring(this.file.name.lastIndexOf(".") + 1).toLowerCase() if (ext != "png" && ext != "jpg" && ext != "jpeg") { alert("圖片的格式必須為png或者jpg或者jpeg格式!") return } reader.onload = (e) => { let src = e.target.result let img = new Image() img.src = src let w = img.width let h = img.height this.fitch(w, h, img) } reader.readAsDataURL(this.file) }
然后,開始我們的摳圖邏輯代碼之前,先描述一下我的思想:顏色屬性其實(shí)是由RGBA四個(gè)元素組成的,RGB,代表三基色,A代表透明度,當(dāng)A的值為0,則表示這個(gè)顏色是純透明的,所以我們的主要邏輯就是把背景色設(shè)置為透明就好了。
創(chuàng)建一個(gè)canvas畫布,然后把圖片放到這個(gè)畫布中,接著取這個(gè)圖片上下左右四個(gè)點(diǎn)的像素,接下來要扣除這個(gè)圖片的背景,那么,就需要去對(duì)整個(gè)圖片的像素點(diǎn)顏色和背景色之前的區(qū)別,如果顏色相同,則把這個(gè)顏色的透明度設(shè)置成0
fitch(width, height, img) { let dataUrl let c = document.createElement("canvas") c.width = width c.height = height let ctx = c.getContext("2d") ctx.drawImage(img, 0, 0) /** * 取圖片四個(gè)腳邊的像素點(diǎn)rgba * @type {*} */ let tl = Array.prototype.slice.call(ctx.getImageData(0, 0, 1, 1).data).join(",") let tr = Array.prototype.slice.call(ctx.getImageData(width - 1, 0, 1, 1).data).join(",") let br = Array.prototype.slice.call(ctx.getImageData(width - 1, height - 1, 1, 1).data).join(",") let bl = Array.prototype.slice.call(ctx.getImageData(0, height - 1, 1, 1).data).join(",") let imgdata = [tl, tr, bl, br] // 四個(gè)取色點(diǎn) let selfImageData = [] // 當(dāng)前rgba imgdata.sort() // 目前只支持純色背景摳圖,簡(jiǎn)單的判斷是否為純色 let deferNum = this.unique(imgdata).length if (deferNum <= 1) { { selfImageData = imgdata[1].split(",") // 設(shè)置要扣除的主題色 let isPNG = true // 判斷是否已經(jīng)扣過 let imgDataUrl = ctx.getImageData(0, 0, width, height) //獲取像素點(diǎn) let data = imgDataUrl.data for (let i = 0; i < data.length; i += 4) { // 得到 RGBA 通道的值 let r = data[i] let g = data[i + 1] let b = data[i + 2] /** * function 判斷顏色是不是屬于背景色 * @param numerical * @param index * @returns {boolean} */ let isIn = (numerical, index) => { if (selfImageData[3] == 0) { isPNG = false return false } return numerical > parseInt(selfImageData[index]) && numerical < parseInt(selfImageData[index])// 去掉邊緣色 } if ([r, g, b].every(isIn)) { data[i + 3] = 0 // 設(shè)置背景透明 } } // 將修改后的代碼復(fù)制回畫布中 ctx.putImageData(imgDataUrl, 0, 0) dataUrl = c.toDataURL("image/png") if (isPNG) { /** * 創(chuàng)建下載鏈接 進(jìn)行圖片下載 * @type {Element} */ let a = document.createElement("a") a.href = dataUrl //下載圖片 a.download = "未命名.png" a.click() } else { alert("背景已摳除!") } } } else { alert("只支持純色背景摳圖!") } }
然后我們測(cè)試一下效果:創(chuàng)建index.html
Title
然后我們選擇一個(gè)純色背景圖
摳圖后,我們看看:
確實(shí)完成了摳圖。
當(dāng)然實(shí)現(xiàn)算法還不是很完善,主要是為了給大家展示canvas的無限可能,當(dāng)然我也在逐步優(yōu)化算法中,使得圖片摳圖更加完美,更加智能,也歡迎大家的star, pullrequest
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82287.html
摘要:組件提供了一系列的操作接口以方便用戶對(duì)彈幕的相關(guān)特性進(jìn)行定制。對(duì)于這種類型的圖像,我們可以使用色鍵的方式進(jìn)行摳圖生成蒙版。其中,用于更新蒙版的接口為。 導(dǎo)讀:本文內(nèi)容是筆者最近實(shí)現(xiàn)的 web 端彈幕組件—— Barrage UI 的一個(gè)延伸。在閱讀本文的實(shí)例和相關(guān)代碼之前,不妨先瀏覽項(xiàng)目文檔,對(duì)組件的使用方式和相關(guān)接口進(jìn)行了解。 各位童鞋如果經(jīng)常上 B 站(bilibili.com) ...
摘要:只有源圖像外的目標(biāo)圖像部分會(huì)被顯示,源圖像是透明的。繪制了線路的圖像是目標(biāo)圖像,線路是源圖像。 楔子 最近一個(gè)項(xiàng)目,需要繪制雙線的效果,雙線效果表示的是軌道(類似鐵軌之類的),如下圖所示: 負(fù)責(zé)這塊功能開發(fā)的小伙,姑且稱之為L(zhǎng)吧,最開始是通過數(shù)學(xué)計(jì)算的方式來實(shí)現(xiàn)這種雙線,也就是在原來的路徑的基礎(chǔ)上,計(jì)算出兩條路徑。但是這個(gè)過程的計(jì)算算挺復(fù)雜,而是最終實(shí)現(xiàn)的效果很耗性能,性能損耗估計(jì)主要...
摘要:下面就講解一下,移動(dòng)端上傳照片,旋轉(zhuǎn),摳圖以及圖片美白效果原理。 下面就講解一下,移動(dòng)端上傳照片,旋轉(zhuǎn),摳圖,以及圖片美白效果原理。 一、上傳照片 下面是兩種上傳照片的方法 1、此方法被廢棄,希望能給大家一點(diǎn)提示,和思考的空間 a、通過改變file的值獲取圖片路徑,并把路徑添加到img元素中,在頁(yè)面中展示 b、圖片上傳,可以用form表單上傳,但是獲取不到返回值,可以用ajaxfil...
閱讀 948·2021-11-22 12:09
閱讀 3715·2021-09-27 13:36
閱讀 1403·2021-08-20 09:37
閱讀 4027·2019-12-27 12:22
閱讀 2365·2019-08-30 15:55
閱讀 2370·2019-08-30 13:16
閱讀 2832·2019-08-26 17:06
閱讀 3442·2019-08-23 18:32