谋智社区

火狐浏览器在中国

颠覆网络35天 ─ 使用Canvas操作像素

July 3rd, 2009

原文地址:http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/

系列地址:颠覆网络35天

====================================

这篇文章由Paul Rouget创作,Paul是Mozilla Evangelism团队成员,生活在法国巴黎,以在开放互联网视频方面的卓越工作而被大家熟知。

Canvas,最简单的来描述他就是一种最直接简便的方法可以允许您在HTML页面上绘画位图。他提供了方法可以直接绘画矩形、弧线、曲线等其他简单图形元素。不过有时候,为了某些特殊效果您需要直接能够访问到像素信息。

在Firefox 3.5中,我们为Canvas元素添加了一个新的方法──createImageDatacreateImageData是一个非常便利的方式用来生成全空的像素集合用来控制从而画回到Canvas上。

既然我们开始讨论这个调用,那么我们想最好能够从头到尾为您描述这一调用的全过程,包括读取、控制和更新在Canvas上的像素,从而了解如何更好的使用createImageData

获取像素数据

您不能直接在Canvas中控制像素。为了改变在Canvas的数据,您需要先把数据拷贝出来,然后改变数据,最后在把修改好的数据重新画到目标Canvas上。

方法getImageData可以让您从Canvas中拷贝某一矩形区域的像素数据。具体的调用代码如下:


var canvas = document.getElementById(‘myCanvasElt’);
var ctx = canvas.getContext(‘2d’);
var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);

canvasData对象中包含了需要的像素数据。他具有下面这些成员变量:


canvasData {
    width: unsigned long, // the width of the canvas
    height: unsigned long, // the height of the canvas
    data: CanvasPixelArray // the values of the pixels
}

其中成员变量data是一个展开的数组,按照一定顺序对应着每个像素中的颜色组成部分,依据从左到右、从上到下的顺序描述像素,而每个像素还包括四个值对应着RGBA。

例如,在一个2×2的Canvas中,应该有如下16个值来描述4个像素点:

RGBA RGBA RGBA RGBA

所以您可以使用下面的公式来计算数组的长度:width * height * 4

在一个大一些的Canvas中,如果您想知道在x=10、y=20这个坐标上像素的蓝色值是多少,可以使用下面示例的代码:


var x = 10;
var y = 10;
var blue = canvasData.data[(y * width + x) * 4 + 2];

注意,每个RGB像素值取值在0到255之间,Alpha也取值于0到255之间──0表示完全的透明255表示完全的不透明。

生成新的像素集合

如果您希望完全从新生成像素矩阵,可以使用createImageData函数,并需要提供两个参数:矩阵的宽度和高度。

需要注意的是,createImageData调用并不会从现有的Canvas中拷贝像素出来,他生成的是完全空白的像素矩阵,他的初始值是全透明的黑色,即 (255,255,255,0) 。

下面的示例展示如何生成像素集合可以适合Canvas的大小:


var canvas = document.getElementById(‘myCanvasElt’);
var ctx = canvas.getContext(‘2d’);
var canvasData = ctx.createImageData(canvas.width, canvas.height);

需要注意的是,如果您希望新建像素数据,就应该调用这个方法。以前版本的Firefox直接使用JavaScript对象来构建canvasData对象,之后用来更新Canvas的数据。这个调用被添加进来从而保持和WebKit的兼容,但是在底层使用的是特定的对象而非简单的纯JavaScript对象了。

更新像素数据

当您拥有canvasData对象之后,您就可以通过其中的数据数组来更新特定的像素值了。下面的示例就展示了如何遍历数据来读取和更新这些数值。


for (var x = 0; x < canvasData.width; x++)  {
    for (var y = 0; y < canvasData.height; y++)  {
        // Index of the pixel in the array
        var idx = (x + y * width) * 4;
        // If you want to know the values of the pixel
        var r = canvasData.data[idx + 0];
        var g = canvasData.data[idx + 1];
        var b = canvasData.data[idx + 2];
        var a = canvasData.data[idx + 3];
        //[…] do what you want with these values
        // If you want to update the values of the pixel
        canvasData.data[idx + 0] =; // Red channel
        canvasData.data[idx + 1] =; // Green channel
        canvasData.data[idx + 2] =; // Blue channel
        canvasData.data[idx + 3] =; // Alpha channel
    }
}

更新Canvas

现在您已经更新了像素集合,可以简单的调用putImageData来更新Canvas。这个调用需要canvasData和x,y位置参数来控制更新Canvas的矩形数据信息:


var canvas = document.getElementById(‘myCanvasElt’);
var ctx = canvas.getContext(‘2d’);
var canvasData = ctx.putImageData(canvasData, 0, 0);

getImageData的完整示例

下面这段代码把一个彩色图片转换为灰度图片。您也可以在Paul的网站上看到演示的效果。


var canvas = document.getElementById(‘myCanvasElt’);
var ctx = canvas.getContext(‘2d’);
var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (var x = 0; x < canvasData.width; x++) {
    for (var y = 0; y < canvasData.height; y++) {
        // Index of the pixel in the array
        var idx = (x + y * canvas.width) * 4;
        // The RGB values
        var r = canvasData.data[idx + 0];
        var g = canvasData.data[idx + 1];
        var b = canvasData.data[idx + 2];
        // Update the values of the pixel;
        var gray = (r + g + b) / 3;
        canvasData.data[idx + 0] = gray;
        canvasData.data[idx + 1] = gray;
        canvasData.data[idx + 2] = gray;
    }
}
ctx.putImageData(canvasData, 0, 0);

createImageData的完整示例

下面的代码会在Canvas上画出一副分形图案。同样,您可以在Paul的网站上查看演示效果。


var canvas = document.getElementById(‘myCanvasElt’);
var ctx = canvas.getContext(‘2d’);
var canvasData = ctx.createImageData(canvas.width, canvas.height);// Mandelbrot
function computeColor(x, y) {
    x = 2.5 * (x/canvas.width - 0.5);
    y = 2 * (y/canvas.height - 0.5);
    var x0 = x;
    var y0 = y;
     var iteration = 0;
     var max_iteration = 100;
     while (x * x + y * y <= 4 && iteration < max_iteration ) {
          var xtemp = x*x - y*y + x0;
          y = 2*x*y + y0;
          x = xtemp;
          iteration++;
     }
     return Math.round(255 * iteration / max_iteration);
}
for (var x = 0; x < canvasData.width; x++) {
     for (var y = 0; y < canvasData.height; y++) {
          var color = computeColor(x, y);
          // Index of the pixel in the array
          var idx = (x + y * canvas.width) * 4;
          // Update the values of the pixel;
          canvasData.data[idx + 0] = color;
          canvasData.data[idx + 1] = color;
          canvasData.data[idx + 2] = color;
          canvasData.data[idx + 3] = 255;
     }
}
ctx.putImageData(canvasData, 0, 0);

更多文档

如果想了解更多关于Canvas的内容,我们强烈建议您浏览MDC(Mozilla开发者中心)上有关Canvas的文档:

我们希望这些能够帮助所有人。


No Comments »

颠覆网络35天 ─ 让我们共同梦想互联网的未来

July 3rd, 2009

(感谢谋智网络工程师MJ的翻译!)

[译] 为了更好的推广Firefox 3.5,怪兽的Evanglist最近开启了一个全新的博客: hacks.mozilla.org。并且在twitter上开启@mozhacks用 以宣传在Firefox 3.5中引入的很多开发者新特性。看到的计划是,准备每天更新两篇,一篇用来介绍Firefox 3.5某项特性的演示,一篇用来讲解某个技术细节,我准备帮助翻译这个系列文章,不过不知道是否有足够的时间和精力,好在他们更新也并不是很多,目前看也都不是特艰深难懂的文章,呵呵,就试试看吧。所有的翻译同样会发布到译言上。

原文地址:http://hacks.mozilla.org/2009/06/35-days/

系列地址:颠覆网络35天

====================================

35 days logo

在接下来的35天内,我们会持续谈论Firefox 3.5中全新的针对开发者提供的新特性。

Firefox 3.5对用户来说是一次很大的升级。这次升级包括全新的隐私浏览特性、在交互性能方面的提升、全新的JavaScript引擎──这点对于使用那些大量使用JavaScript的站点来说尤其重要。这些特性都被广大用户喜欢并津津乐道。

但是Firefox 3.5最终呈现出来的是互联网本身的一次重要升级。我们包括了很多功能支持,例如音频、视频、JavaScript的线程、全新Canvas、大量新 CSS支持、可下载的字体支持以及地理定位等等。如果说之前的Firefox 3对于互联网用户来说是一次巨大提升的话,那么Firefox 3.5就是针对开发者的一次重大升级。

正是因为在Firefox 3.5中这么多重要的开发者特性,我们决定在接下来的35天内逐一讨论这些特性,每天更新两篇博客。每天的第一篇会深度的描述在Firefox 3.5中的某个特性;第二篇会是纯粹的乐趣──我们会把大量人们使用全新Firefox 3.5新特性制作的演示展示在这里。

如我们在Mozilla一直做的一样,这同样是一个社区领导的项目。我们希望能够召集Mozilla的用户和全世界的开发者来发布文章和演示。一些文章会被Mozilla的核心hacker写作,但是更多的文章是被社区中对这些技术非常狂热的爱好者们书写。

我个人相信,这些文章会共同描述出Mozilla对于未来互联网的梦想。我们跟其他的浏览器制造商不同──我们的核心价值在于改善和保护开放互联 网。Firefox 3.5本身要传达的就是我们想象中下一阶段互联网的样子──交互应用、视频、网站协作和共享信息──而这一切全部通过浏览器。

[译] 译言地址:http://www.yeeyan.com/articles/view/mijia/45165


No Comments »

火狐校园大使团队新诗迎接火狐3.5

June 30th, 2009

作者:大连医科大学火狐校园大使 闻海

一:Firefox3.5——新的时代

我们心中满怀着期待
激动的
注视着她的到来
迈着轻盈的脚步
她引领着我们
进入了一个新的时代

你,是否还在电脑前
苦苦的等待着页面的打开?
你,是否对我们
一直都加以青睐?
你是否还对Firefox
有新的期待?

这是一个崭新的时代
Firefox3.5带给你的世界
确实很精彩
只要你愿意
是否可以
张开双臂
拥抱一个
更加迅捷的未来?

二: Firefox3.5——新的世界

远远地,她就在向我们招手
远远地,她就高昂着自信的头
她告诉我们
年轻的她
正引领着的
是一个新的世界
Firefox3.5为您呈现的
更加迅捷的世界!

你突然发现
你与世界的联系可以如此的直接
你突然发现
透过Firefox的窗口
你可以找到想要的一切!

这是一个新的世界
你突然发现
你与世界的联系
竟然可以如此直接


No Comments »

Firefox 3.5今晚发布,让我们把 #fx35 顶上twitter trends!

June 30th, 2009

加油!


No Comments »

[社区活动回顾] Beijing Open Party 6月活动回顾 及 7月活动预告

June 30th, 2009

Beijing Open Party6月活动圆满结束,谋智网络工程师在Beijing Open Party上和大家分享了手机版火狐浏览器Fennec,发几篇博客回顾一下:
————————-
OpenParty “柳岸寻鱼”
http://cnborn.net/blog/2009/06/openparty-looking-fish-at-willowy-bank.html
[这个是一个与Fennec有关的博客]

代码犹如养生――“Looking fish at Willowy bank(柳岸寻鱼)”后记
http://www.beijing-open-party.org/index.php/2009/06/%E4%BB%A3%E7%A0%81%E7%8A%B9%E5%A6%82%E5%85%BB%E7%94%9F%E2%80%95%E2%80%95%E2%80%9Clooking-fish-at-willowy-bank%EF%BC%88%E6%9F%B3%E5%B2%B8%E5%AF%BB%E9%B1%BC%EF%BC%89%E2%80%9D%E5%90%8E%E8%AE%B0.html
[贴图博客,大家能找到关于Fennec的那个Topic么?]
————————-

7月的Beijing Open Pary暂定于7月25日(周六)下午举行,正值火狐3.5发布,我们将设一个“迎接火狐3.5”和“体验火狐3.5”的环节。欢迎大家到时参加哟!

PS:
Bei Jjing Open Party已经发布了“Firefox3.5 Let’s Party”的banner:http://www.beijing-open-party.org/


No Comments »

[Mozilla社区活动] 相聚火狐3.5

June 30th, 2009

亲爱的朋友们,我们来相会!

迎接火狐3.5,超越网络的新一辈!
lets-party-promo

给火狐一个热情的拥抱吧!

Mozilla社区发起“相聚火狐3.5”活动,倡议社区成员自发组织活动庆祝火狐3.5发布!

活动时间

2009年7月(具体日期不做统一规定)

活动方式

——选场地、开Party,庆祝火狐3.5发布,迎接火狐3.5带给我们的网络新世界

——体验火狐3.5,下载火狐3.5,宣传火狐3.5

——致信至info-cn [AT] mozilla.com,了解谋智网络为“相聚火狐3.5”活动提供的支持/资源(来信请注明“火狐3.5Party”,活动礼品有限,先到先得!)

——你也可以在这里了解Mozilla全球“Let’s party like it’s Firefox 3.5!”的活动盛况

火狐3.5有很多超酷的体验,不过最重要的是——喜爱火狐的亲们,可以相聚在一起:-)


No Comments »

Next Page »