canvas的圖片處理
發(fā)表時(shí)間:2024-05-09 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]Canvas 通過(guò) JavaScript 來(lái)繪制 2D圖形。Canvas 是逐像素進(jìn)行渲染的。在canvas 中,一旦圖形被繪制完成,它就不會(huì)繼續(xù)得到瀏覽器的關(guān)注。如果其位置發(fā)生變化,那么整個(gè)場(chǎng)景也需要重新繪制,包括任何或許已被圖形覆蓋的對(duì)象。canvas對(duì)像素點(diǎn)實(shí)現(xiàn)基本的處理操作// ...
Canvas 通過(guò) JavaScript 來(lái)繪制 2D圖形。Canvas 是逐像素進(jìn)行渲染的。在canvas 中,一旦圖形被繪制完成,它就不會(huì)繼續(xù)得到瀏覽器的關(guān)注。如果其位置發(fā)生變化,那么整個(gè)場(chǎng)景也需要重新繪制,包括任何或許已被圖形覆蓋的對(duì)象。
canvas對(duì)像素點(diǎn)實(shí)現(xiàn)基本的處理操作
// 獲取像素點(diǎn)數(shù)據(jù)
var canvas = document.getElementById('CanvasElt');
var ctx = canvas.getContext('2d');
// 獲取canvas中的像素信息,
//x 開始復(fù)制的左上角位置的 x 坐標(biāo)。
//y 開始復(fù)制的左上角位置的 y 坐標(biāo)。
//width 將要復(fù)制的矩形區(qū)域的寬度。
//heigh將要復(fù)制的矩形區(qū)域的高度。
var canvasData = ctx.getImageData(x, y, canvas.width, canvas.height);
// 寫入像素信息
ctx.putImageData(canvasData, 0, 0);
獲取到的canvasData對(duì)象包含下列成員,其中的data數(shù)組結(jié)構(gòu)大概是這樣的,一行一行存,然后一個(gè)列點(diǎn)一個(gè)列點(diǎn)存,每個(gè)點(diǎn)占4個(gè)下標(biāo),分別是RGBA唄,則對(duì)于坐標(biāo)(x,y)(這里的y是下方正向),RGBA分別是data[(ywidth+x)4],data[(ywidth+x)4+1],data[(ywidth+x)4+2],data[(ywidth+x)4+3]。 能夠獲取到像素點(diǎn),就能對(duì)像素點(diǎn)進(jìn)行操作,最簡(jiǎn)單的就是灰度處理了,灰度處理有很多種方式最簡(jiǎn)單的方法就是把每個(gè)相位的r,g,b相加取平均數(shù),再分別賦給r,g,b。
//灰度處理
function gray() {
var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
for(var i = 0; i < imageData.data.length; i += 4) {
var avg = (imageData.data[i] + imageData.data[i + 1] + imageData.data[i + 2]) / 3;
imageData.data[i] = avg; // red
imageData.data[i + 1] = avg; // green
imageData.data[i + 2] = avg; // blue
imageData.data[i + 3] = 255; //alpha
}
ctx1.putImageData(imageData, 0, 0);
}
像素取反:255 減去對(duì)應(yīng)rgb的值,再賦值給原來(lái)的rgb;亮度調(diào)節(jié):原來(lái)的rgb值隨機(jī)的加減一個(gè)相同的隨機(jī)數(shù)。那么想得到對(duì)比度變化的圖片,或者模糊圖片呢? 卷積核: 圖片處理領(lǐng)域最常用的就是卷積核,所謂的矩陣的卷積,就是如下圖顯示的那樣,當(dāng)計(jì)算紅色框中的數(shù)值的時(shí)候,分別先提取周圍綠框中8個(gè)數(shù)字,然后與施加的那個(gè)矩陣中對(duì)應(yīng)位置相乘,然后把各個(gè)乘積加在一起,就得到了最終的值了。
?
比如: (40 x 0)+(42 x 1)+(46 x 0)+ (46 x 0)+(50 x 0)+(55 x 0)+ (52 x 0)+(56 x 0)+(58 x 0)= 42 那怎么就能得到模糊的圖片呢?圖片的像素點(diǎn)和[1,1,1,1,1,1,1,1,1]的矩陣求卷積核,此時(shí)的像素點(diǎn)可能超過(guò)了255;所以再除以一個(gè)基數(shù)8;得到的圖片就是加了模糊濾鏡的圖片;對(duì)比度呢,就是1.提高白色畫面的亮度;2.讓黑色更黑,降低最低亮度;可以求[0,0,0,0,3,0,0,0,0]的卷積核,同樣的有可能超過(guò)255,再減去一個(gè)適合的基數(shù)150; 現(xiàn)在需要一個(gè)卷積核的函數(shù): 函數(shù)第一個(gè)參數(shù)是 canvas上的 imageData 對(duì)象 第二個(gè)參數(shù)是傳入矩陣所對(duì)應(yīng)的數(shù)組,如果是下面這樣的矩陣 a b c d e f g h i 則傳入第二個(gè)的參數(shù)應(yīng)為 [a,b,c,d,e,f,g,h,i] 第三個(gè)參數(shù)是除數(shù)因子。 第四個(gè)參數(shù)就是偏移量。
function ConvolutionMatrix(input, m, pisor, offset) {
var output =document.createElement("canvas").getContext('2d').createImageData(input);
var w = input.width,
h = input.height;
var iD = input.data,
oD = output.data;
for(var y = 1; y < h - 1; y += 1) {
for(var x = 1; x < w - 1; x += 1) {
for(var c = 0; c < 3; c += 1) {
var i = (y * w + x) * 4 + c;
// 卷積核計(jì)算
oD[i] = offset +(m[0] * iD[i - w * 4 - 4] + m[1] * iD[i - w * 4] + m[2] * iD[i - w * 4 + 4] +m[3] * iD[i - 4] + m[4] * iD[i] + m[5] * iD[i + 4] +m[6] * iD[i + w * 4 - 4] + m[7] * iD[i + w * 4] + m[8] * iD[i + w * 4 + 4]) /pisor;
}
oD[(y * w + x) * 4 + 3] = 255; // 設(shè)置透明度為不透明
}
}
return output;
}
//模糊處理
function mohu(){
var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
var m = [1,1,1,1,1,1,1,1,1];
var output = ConvolutionMatrix(imageData, m, 10,0);
ctx1.putImageData(output,0,0);
}
//對(duì)比度處理
function level(){
var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
var m = [0,0,0,0,3,0,0,0,0];
var output = ConvolutionMatrix(imageData, m, 1,-150);
ctx1.putImageData(output,0,0);
}
圖片也可以有你想要的數(shù)據(jù)
既然圖片每個(gè)像素都是由RGBA四個(gè)元素構(gòu)成,單純以圖片來(lái)說(shuō)用getImageData解析出來(lái)的只是一大堆你不必需要知道的數(shù)據(jù),那么我們是不是可以把特定的色值看成我們自己的數(shù)據(jù)呢?
比如:在一張圖片中,我們想把(r:255,g:255:b:255,a:255)白色像素找出來(lái),可以通過(guò)getImageData來(lái)獲取圖片的數(shù)據(jù),通過(guò)檢索每個(gè)像素的數(shù)據(jù)是不是對(duì)應(yīng)的rgba,把它們提取出來(lái),再根據(jù)圖片的寬度和高度,就可以計(jì)算出每個(gè)白色像素的位置信息,這些信息就是你想要提取的數(shù)據(jù)。
圖片也需要做的好遍歷些
在上一步中,我們已經(jīng)知道了圖片中特定元素獲取相關(guān)位置信息的操作,但是圖片是一個(gè)很普通的圖片的話,你就需要遍歷imageData中每個(gè)信息,有沒(méi)有更好的方式減少遍歷呢?
答案是:圖片默認(rèn)為黑色(r:0,g:0,b:0,a:0)就可以了,但不一定只有一個(gè)答案,或許也會(huì)有其他好的方法,但原理應(yīng)該是一樣的。
通過(guò)遍歷每個(gè)像素的r,如果r!=0再去遍歷這個(gè)像素的剩下的g,b,a,這一步比上一步剩下了無(wú)用的遍歷,這一步中最重要的就是背景最好是黑色,因?yàn)楹谏侨銧顟B(tài),好計(jì)算。
還有沒(méi)有更好的優(yōu)化?
除了上述兩步外,所用到的圖片太大,也會(huì)導(dǎo)致遍歷更多,而且我們只關(guān)心的是提取數(shù)據(jù),而不關(guān)心他的大小,最終數(shù)據(jù)是我們想要的就行,那么我們可以把原圖可以按比例縮放幾倍,利用新的圖片獲取的數(shù)據(jù)最后在乘以相應(yīng)的倍數(shù),所得的就是我們想要的數(shù)據(jù)了。
相關(guān)推薦:
Canvas處理圖片的方法
怎樣用canvas實(shí)現(xiàn)小球和鼠標(biāo)的互動(dòng)
JavaScript+html5 canvas實(shí)現(xiàn)圖片上畫超鏈接的示例代碼
以上就是canvas的圖片處理 的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
網(wǎng)站建設(shè)是一個(gè)廣義的術(shù)語(yǔ),涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護(hù)的網(wǎng)站。