18.
从零绘制图像这一节我们可以开始制作一些真正漂亮的图像了,例如从创建像素开始制作自己的图像.
要创建一些像素,需要调用2D渲染上下文的createImageData方法.
通过传入宽度和高度,它会返回一个包含所有常规属性的ImageData对象:width、height和(最重要的)data.
data属性所包含的CanvasPixelArray将保存新的像素,此时它们是不可见的,因为它们都被设置为透明黑色.
在下一个例子中,我们将创建一个包含200*200透明像素区域的ImageData对象,然后将它们全部修改成红色.
varimageData=context.
createImageData(200,200);varpixels=imageData.
data;变量pixels仅用作访问CanvasPixelArray中的像素的快捷方式.
修改颜色值与查询颜色值一样简单:都是读写CanvasPixelArray中的颜色值.
如果想将所有像素修改为红色,那么需要使用for循环语句遍历每一个像素.
varnumPixels=imageData.
width*imageData.
height;for(vari=0;i
每个像素都有4个颜色值,所以将像素个数乘以4就能够得到该像素的红色颜色值在CanvasPixelArray中的索引位置.
然后,就可以将红色颜色值设置为255(全色),绿色和蓝色设置为0,而阿尔法值设置为255,这样它就变成不透明的r.
非常简单!
按照目前情况,我们所做的就是创建一个ImageData,然后将像素修改为红色.
现在画布上还看不见任何效果,因为我们还没有将新像素画到上面.
为此,我们需要调用2D渲染上下文的putImageData方法.
这个方法可以接受3个或7个参数:ImageData对象、绘制像素数据的原点坐标(x,y)、所谓脏矩形(dirtyrectangle)的原点坐标(x,y),脏矩形的宽度和高度.
在这个例子中,你暂时可以不考虑脏矩形的用途,它的作用只是定义ImageData对象中需要绘制的像素.
context.
putImageData(imageData,0,0);这样会在画布原点绘制新的红色像素(参见图1).
图1从零开始创建和绘制像素随机绘制像素只有红色像素似乎太单调,让我们更进一步,绘制一些完全随机的颜色.
这也很简单.
for(vari=0;i
random()*255);//Redpixels[i*4+1]=Math.
floor(Math.
random()*255);//Greenpixels[i*4+2]=Math.
floor(Math.
random()*255);//Bluepixels[i*4+3]=255;//Alpha};通过修改前一个例子中设置颜色值的代码,我们可以插入0至255之间的随机数.
我们仍然保持阿尔法值为255,否则有一些像素会变成透明的.
注意,我们使用了Math.
floor来向下舍入产生的随机数(例如,150.
456会变成150).
结果,我们得到一些杂乱的像素点(参见图2).
注意:Math.
random可以产生0到1之间的随机小数.
将它与另一个数字相乘,就可以得到0与该数字(乘数)之间的随机数.
例如,Math.
random()*255将得到0与255之间的一个随机数.
图2随机设置在画布上绘制的像素的颜色创建马赛克效果但是,杂乱的像素并不是画布的最佳用途.
那么创建一个马赛克效果呢肯定更有意思一些.
它的实现方法是,创建一个新像素区域,然后将它分割到一个栅格中,并为栅格每个片段设置随机颜色.
最复杂的部分是计算出每个像素应该落到哪个片段,这样相同的片段就可以设置相同的颜色.
在图3中,我们会看到每个片段实际上是由许多像素构成的.
图3将画布分割到像素片段栅格中稍后,我会介绍如何计算出每个片段的像素.
现在,先来做一些基础性工作.
varimageData=context.
createImageData(500,500);varpixels=imageData.
data;//NumberofmosaictilesvarnumTileRows=4;varnumTileCols=4;//DimensionsofeachtilevartileWidth=imageData.
width/numTileCols;vartileHeight=imageData.
height/numTileRows;前两行代码现在你应该很熟悉了,它们创建了一个500*500像素的ImageData对象,然后将CanvasPixelArray保存在一个变量中.
后面的代码是定义两个变量,用于声明像素区域划分的片段数,其中包括每行每列的马赛克数.
从现在起,我们将片段称为块(tile),因为这个词更能说明它们的实际作用.
最后两行代码是根据ImageData对象的尺寸和各行各列的块数计算出每个块的宽度和高度(以像素为单位).
现在,我们有了足够信息,可以开始遍历这些块和修改像素的颜色值.
for(varr=0;r
random()*255);vargreen=Math.
floor(Math.
random()*255);varblue=Math.
floor(Math.
random()*255);};};这是一个嵌套循环,第一个循环遍历每一行的块,第二个循环遍历当前行的每一列块(参见图4左边的栅格).
每一个块都赋了新的颜色值,这些值都是0至255的随机数.
到现在为止,所有代码都是非常基础的.
现在,在列循环中颜色值的下方,我们要声明另外两个循环:for(vartr=0;tr
在这个例子中,每一个块的宽和高都是125像素,所以tr将会循环125次,而在每一次循环中,tc将会再循环125次.
图4循环每一个块和块中每一个像素然而,我们现在仍然还无法访问每一个块中的实际像素.
我们现在得到的是所访问的块的行和列(变量r和c),以及你在该块中所处的像素的行和列(变量tr和tc)对于它们本身而言,这些变量并不足以用来访问CanvasPixelArray中的像素.
为此,需要将它们转换为以0开始的像素位置坐标(x,y),就像是没有块存在时那样.
RackNerd 商家从2019年上线以来争议也是比较大的,一直低价促销很多网友都认为坚持时间不长可能会跑路。不过,目前看到RackNerd还是在坚持且这次黑五活动也有发布,且活动促销也是比较多的,不过对于我们用户来说选择这些低价服务商尽量的不要将长远项目放在上面,低价年付套餐服务商一般都是用来临时业务的。RackNerd商家这次发布黑五促销活动,一共有五款年付套餐,涉及到多个机房。最低年付的套餐...
webhosting24决定从7月1日开始对日本机房的VPS进行NVMe和流量大升级,几乎是翻倍了硬盘和流量,当然前提是价格依旧不变。目前来看,国内过去走的是NTT直连,服务器托管机房应该是CDN77*(也就是datapacket.com),加上高性能平台(AMD Ryzen 9 3900X+NVMe),这样的日本VPS还是有相当大的性价比的。官方网站:https://www.webhosting...
inlicloud怎么样?inlicloud(引力主机)主要产品为国内NAT系列VPS,目前主要有:上海联通NAT(200Mbps带宽)、宿州联通NAT(200Mbps带宽)、广州移动NAT(200Mbps带宽)。根据官方的说法国内的NAT系列VPS不要求备案、不要求实名、对中转要求也不严格,但是,禁止任何形式的回国!安徽nat/上海联通/广州移动/江门移动nat云主机,2核1G/200Mbps仅...