摘要:當然實現算法還不是很完善,主要是為了給大家展示的無限可能,當然我也在逐步優化算法中,使得圖片摳圖更加完美,更加智能,也歡迎大家的
最近在研究html5 canvas的過程中,發現,canvas為前端對圖像的處理開辟了一條新的道路,canvas可以做到很多事情,甚至可以做個類似于PhotoShop的東西,曾經本人在一家軟件工作就做類似的工作,可以看一下我之前開發的軟件:
這個就是canvas實現的類似于Adobe Photoshop,足以見得canvas的強大之處!
本文就是抽出其中一個小的功能點,來簡單聊聊canvas強大之處:我們來一步步實現一個簡單的智能摳圖功能:(具體的代碼見我的github:monkeyWangs/Matting)
1.環境準備
本人采用ES6語法作為開發環境,選用webpack作為構建工具,于是乎,我們有了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"), /* 靜態目錄,可以直接從這里取文件 */ publicPath: "/dist/", /* 文件名 */ filename: "matting.js" }, module: { rules: [ /* 用babel來解析js文件并把es6的語法轉換成瀏覽器認識的語法 */ { test: /.js$/, loader: "babel-loader", /* 排除模塊安裝目錄的文件 */ exclude: /node_modules/ } ] } }
這樣變準備好了開發用的基本環境,接下來我們來實現具體的核心代碼,為了方便起見,我的代碼全寫在了inde.js
2.代碼實現
首選我們需要新建一個對象:
/** * @author monkeywang * Date: 17/3/30 */ class Matting { }
然后我們需要接受用戶上傳的圖片文件:
class Matting { /** * 構造函數 * @param file */ constructor(file) { this.file = file } }
再接著把圖片文件轉成base64格式,所以我們在類中建了一個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) }
然后,開始我們的摳圖邏輯代碼之前,先描述一下我的思想:顏色屬性其實是由RGBA四個元素組成的,RGB,代表三基色,A代表透明度,當A的值為0,則表示這個顏色是純透明的,所以我們的主要邏輯就是把背景色設置為透明就好了。
創建一個canvas畫布,然后把圖片放到這個畫布中,接著取這個圖片上下左右四個點的像素,接下來要扣除這個圖片的背景,那么,就需要去對整個圖片的像素點顏色和背景色之前的區別,如果顏色相同,則把這個顏色的透明度設置成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) /** * 取圖片四個腳邊的像素點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] // 四個取色點 let selfImageData = [] // 當前rgba imgdata.sort() // 目前只支持純色背景摳圖,簡單的判斷是否為純色 let deferNum = this.unique(imgdata).length if (deferNum <= 1) { { selfImageData = imgdata[1].split(",") // 設置要扣除的主題色 let isPNG = true // 判斷是否已經扣過 let imgDataUrl = ctx.getImageData(0, 0, width, height) //獲取像素點 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 // 設置背景透明 } } // 將修改后的代碼復制回畫布中 ctx.putImageData(imgDataUrl, 0, 0) dataUrl = c.toDataURL("image/png") if (isPNG) { /** * 創建下載鏈接 進行圖片下載 * @type {Element} */ let a = document.createElement("a") a.href = dataUrl //下載圖片 a.download = "未命名.png" a.click() } else { alert("背景已摳除!") } } } else { alert("只支持純色背景摳圖!") } }
然后我們測試一下效果:創建index.html
Title
然后我們選擇一個純色背景圖
摳圖后,我們看看:
確實完成了摳圖。
當然實現算法還不是很完善,主要是為了給大家展示canvas的無限可能,當然我也在逐步優化算法中,使得圖片摳圖更加完美,更加智能,也歡迎大家的star, pullrequest
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82287.html
摘要:組件提供了一系列的操作接口以方便用戶對彈幕的相關特性進行定制。對于這種類型的圖像,我們可以使用色鍵的方式進行摳圖生成蒙版。其中,用于更新蒙版的接口為。 導讀:本文內容是筆者最近實現的 web 端彈幕組件—— Barrage UI 的一個延伸。在閱讀本文的實例和相關代碼之前,不妨先瀏覽項目文檔,對組件的使用方式和相關接口進行了解。 各位童鞋如果經常上 B 站(bilibili.com) ...
摘要:只有源圖像外的目標圖像部分會被顯示,源圖像是透明的。繪制了線路的圖像是目標圖像,線路是源圖像。 楔子 最近一個項目,需要繪制雙線的效果,雙線效果表示的是軌道(類似鐵軌之類的),如下圖所示: 負責這塊功能開發的小伙,姑且稱之為L吧,最開始是通過數學計算的方式來實現這種雙線,也就是在原來的路徑的基礎上,計算出兩條路徑。但是這個過程的計算算挺復雜,而是最終實現的效果很耗性能,性能損耗估計主要...
摘要:下面就講解一下,移動端上傳照片,旋轉,摳圖以及圖片美白效果原理。 下面就講解一下,移動端上傳照片,旋轉,摳圖,以及圖片美白效果原理。 一、上傳照片 下面是兩種上傳照片的方法 1、此方法被廢棄,希望能給大家一點提示,和思考的空間 a、通過改變file的值獲取圖片路徑,并把路徑添加到img元素中,在頁面中展示 b、圖片上傳,可以用form表單上傳,但是獲取不到返回值,可以用ajaxfil...
閱讀 929·2021-11-22 12:09
閱讀 3704·2021-09-27 13:36
閱讀 1390·2021-08-20 09:37
閱讀 4007·2019-12-27 12:22
閱讀 2353·2019-08-30 15:55
閱讀 2358·2019-08-30 13:16
閱讀 2817·2019-08-26 17:06
閱讀 3433·2019-08-23 18:32