創(chuàng)建馬賽克效果_第1頁(yè)
創(chuàng)建馬賽克效果_第2頁(yè)
創(chuàng)建馬賽克效果_第3頁(yè)
創(chuàng)建馬賽克效果_第4頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余1頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、18從零繪制圖像這一節(jié)我們可以開(kāi)始制作一些真正漂亮的圖像了,例如從創(chuàng)建像素開(kāi)始制作自己的圖 像。要?jiǎng)?chuàng)建一些像素, 需要調(diào)用 2D 渲染上下文的 createImageData 方法。 通過(guò)傳入寬度和高 度,它會(huì)返回一個(gè)包含所有常規(guī)屬性的ImageData 對(duì)象: width 、height 和(最重要的) data。data 屬性所包含的 CanvasPixelArray 將保存新的像素,此時(shí)它們是不可見(jiàn)的,因?yàn)樗鼈兌急?設(shè)置為透明黑色。在下一個(gè)例子中,我們將創(chuàng)建一個(gè)包含200 200 透明像素區(qū)域的 ImageData 對(duì)象,然后將它們?nèi)啃薷某杉t色。var imageData = cont

2、ext.createImageData(200, 200);var pixels = imageData.data;變量 pixels 僅用作訪問(wèn) CanvasPixelArray 中的像素的快捷方式。修改顏色值與查詢(xún)顏色值一樣簡(jiǎn)單:都是讀寫(xiě)CanvasPixelArray 中的顏色值。如果想將所有像素修改為紅色,那么需要使用 for 循環(huán)語(yǔ)句遍歷每一個(gè)像素。var numPixels = imageData.width*imageData.height;for (var i = 0; i numPixels; i+) pixelsi*4 = 255; / Redpixelsi*4+1 = 0

3、; / Greenpixelsi*4+2 = 0; / Bluepixelsi*4+3 = 255; / Alpha;變量 numPixels 保存了 ImageData 對(duì)象中的像素個(gè)數(shù),它就是 for 循環(huán)的執(zhí)行次數(shù)。在 每一次循環(huán)過(guò)程中, 我們都使用一個(gè)簡(jiǎn)單算法給每個(gè)像素賦予顏色值。 每個(gè)像素都有 4 個(gè)顏 色值,所以將像素個(gè)數(shù)乘以 4 就能夠得到該像素的紅色顏色值在 CanvasPixelArray 中的索引 位置。然后,就可以將紅色顏色值設(shè)置為255(全色),綠色和藍(lán)色設(shè)置為 0,而阿爾法值設(shè)置為 255,這樣它就變成不透明的 r。非常簡(jiǎn)單!按照目前情況,我們所做的就是創(chuàng)建一個(gè)Ima

4、geData ,然后將像素修改為紅色?,F(xiàn)在畫(huà)布上還看不見(jiàn)任何效果,因?yàn)槲覀冞€沒(méi)有將新像素畫(huà)到上面。為此,我們需要調(diào)用2D 渲染上下文的 putImageData 方法。 這個(gè)方法可以接受 3 個(gè)或 7 個(gè)參數(shù): ImageData 對(duì)象、繪制像 素?cái)?shù)據(jù)的原點(diǎn)坐標(biāo)( x, y)、所謂臟矩形 (dirty rectangle) 的原點(diǎn)坐標(biāo)( x, y),臟矩形的寬度 和高度。在這個(gè)例子中,你暫時(shí)可以不考慮臟矩形的用途,它的作用只是定義 ImageData 對(duì) 象中需要繪制的像素。context.putImageData(imageData, 0, 0);這樣會(huì)在畫(huà)布原點(diǎn)繪制新的紅色像素(參見(jiàn)圖1)

5、。1 / 5圖 1 從零開(kāi)始創(chuàng)建和繪制像素隨機(jī)繪制像素只有紅色像素似乎太單調(diào),讓我們更進(jìn)一步,繪制一些完全隨機(jī)的顏色。這也很簡(jiǎn)單。for (var i = 0; i numPixels; i+) pixelsi*4 = Math.floor(Math.random()*255); / Redpixelsi*4+1 = Math.floor(Math.random()*255); / Greenpixelsi*4+2 = Math.floor(Math.random()*255); / Bluepixelsi*4+3 = 255; / Alpha;通過(guò)修改前一個(gè)例子中設(shè)置顏色值的代碼, 我們可以

6、插入 0 至 255 之間的隨機(jī)數(shù)。 我們 仍然保持阿爾法值為 255,否則有一些像素會(huì)變成透明的。注意,我們使用了Math.floor 來(lái)向下舍入產(chǎn)生的隨機(jī)數(shù)(例如, 150.456 會(huì)變成 150)。結(jié)果,我們得到一些雜亂的像素點(diǎn)(參見(jiàn)圖 2)。注意 :Math.random 可以產(chǎn)生 0 到 1 之間的隨機(jī)小數(shù)將它與另一個(gè)數(shù)字相乘,就可以 得到 0 與該數(shù)字(乘數(shù))之間的隨機(jī)數(shù)。例如, Math.random()*2 55 將得到 0 與 255 之間的 一個(gè)隨機(jī)數(shù)。圖2 隨機(jī)設(shè)置在畫(huà)布上繪制的像素的顏色創(chuàng)建馬賽克效果但是, 雜亂的像素并不是畫(huà)布的最佳用途。 那么創(chuàng)建一個(gè)馬賽克效果呢?肯

7、定更有意思 一些。 它的實(shí)現(xiàn)方法是, 創(chuàng)建一個(gè)新像素區(qū)域,然后將它分割到一個(gè)柵格中,并為柵格每個(gè) 片段設(shè)置隨機(jī)顏色。 最復(fù)雜的部分是計(jì)算出每個(gè)像素應(yīng)該落到哪個(gè)片段, 這樣相同的片段就 可以設(shè)置相同的顏色。在圖 3 中,我們會(huì)看到每個(gè)片段實(shí)際上是由許多像素構(gòu)成的。圖 3 將畫(huà)布分割到像素片段柵格中 稍后,我會(huì)介紹如何計(jì)算出每個(gè)片段的像素?,F(xiàn)在,先來(lái)做一些基礎(chǔ)性工作。var imageData = context.createImageData(500, 500);var pixels = imageData.data;/ Number of mosaic tilesvar numTileRows

8、 = 4;var numTileCols = 4;/ Dimensions of each tilevar tileWidth = imageData.width/numTileCols;var tileHeight = imageData.height/numTileRows;前兩行代碼現(xiàn)在你應(yīng)該很熟悉了,它們創(chuàng)建了一個(gè)500 500 像素的 ImageData 對(duì)象,然后將 CanvasPixelArray 保存在一個(gè)變量中。后面的代碼是定義兩個(gè)變量,用于聲明像素區(qū) 域劃分的片段數(shù),其中包括每行每列的馬賽克數(shù)。從現(xiàn)在起,我們將片段稱(chēng)為塊 (tile) ,因?yàn)?這個(gè)詞更能說(shuō)明它們的實(shí)際作用。

9、 最后兩行代碼是根據(jù) ImageData 對(duì)象的尺寸和各行各列的 塊數(shù)計(jì)算出每個(gè)塊的寬度和高度(以像素為單位) 。現(xiàn)在,我們有了足夠信息,可以開(kāi)始遍歷這些塊和修改像素的顏色值。for (var r = 0; r numTileRows; r+) for (var c = 0; c numTileCols; c+) / Set the pixel values for each tilevar red = Math.floor(Math.random()*255);var green = Math.floor(Math.random()*255);var blue = Math.floor(Ma

10、th.random()*255);這是一個(gè)嵌套循環(huán), 第一個(gè)循環(huán)遍歷每一行的塊, 第二個(gè)循環(huán)遍歷當(dāng)前行的每一列塊 (參 見(jiàn)圖 4左邊的柵格) 。每一個(gè)塊都賦了新的顏色值,這些值都是0至 255 的隨機(jī)數(shù)。到現(xiàn)在為止,所有代碼都是非?;A(chǔ)的。現(xiàn)在,在列循環(huán)中顏色值的下方,我們要聲明另外兩個(gè)循環(huán):for (var tr = 0; tr tileHeight; tr+) for (var tc = 0; tc tileWidth; tc+) ;根據(jù)之前計(jì)算的塊尺寸,這些循環(huán)遍歷的次數(shù)與每個(gè)塊中的像素個(gè)數(shù)相同。變量 tr 和 tc 表示當(dāng)前訪問(wèn)塊的像素行(基于塊的高度)和像素列(基于塊的寬度) (參見(jiàn)

11、圖 4 右邊的 柵格)。在這個(gè)例子中,每一個(gè)塊的寬和高都是 125 像素,所以 tr 將會(huì)循環(huán) 125 次,而在每 一次循環(huán)中, tc 將會(huì)再循環(huán) 125 次。圖 4 循環(huán)每一個(gè)塊和塊中每一個(gè)像素然而, 我們現(xiàn)在仍然還無(wú)法訪問(wèn)每一個(gè)塊中的實(shí)際像素。我們現(xiàn)在得到的是所訪問(wèn)的塊的行和列(變量 r 和 c),以及你在該塊中所處的像素的行和列(變量tr 和 tc)對(duì)于它們本身而言,這些變量并不足以用來(lái)訪問(wèn) CanvasPixelArray 中的像素。為此,需要將它們轉(zhuǎn)換為 以 0 開(kāi)始的像素位置坐標(biāo)( x, y),就像是沒(méi)有塊存在時(shí)那樣。將下面的代碼添加到第二個(gè)循環(huán)中, 然后我將解釋會(huì)出現(xiàn)什么結(jié)果,

12、這事實(shí)上是很簡(jiǎn)單 的:var trueX = (c*tileWidth)+tc;var trueY = (r*tileHeight)+tr;這兩個(gè)變量可以計(jì)算出像素的真實(shí)位置。 例如,要計(jì)算 x軸位置, 首先要將當(dāng)前塊的列數(shù)(2)乘以每個(gè)塊的寬度 (125),這樣就得到所訪問(wèn)塊的左邊緣的 x 坐標(biāo)位置 (2125=250)。然 后,再加上所訪問(wèn)的塊中像素的列數(shù) (例如, 10),這樣就得到?jīng)]有塊時(shí)的 x 軸確切坐標(biāo) (250+ 10= 260)。對(duì) y 軸重復(fù)這個(gè)過(guò)程,就可以得到開(kāi)始修改像素顏色值的位置坐標(biāo)(x,y)。將下面的代碼加到 trueX 和 trueY 的賦值語(yǔ)句后面:var pos = (trueY*(imageData.width*4)+(trueX*4);pixelspos = red;pixelspos+1 = green;pixelspos+2 = blue;pixelspos+3 = 255;這里并沒(méi)有出現(xiàn)新代碼, 它只是訪問(wèn)像素的紅色顏色值, 然后使用之前設(shè)置的顏色值進(jìn) 行賦值。因?yàn)檫@里從 0 開(kāi)始計(jì)算,所以必須將 tr

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論