skip to main |skip to sidebar

2007-10-28

[AS3]高级图形处理(1)——自定义颜色比率的噪音(Noise)

一般制作线性噪音(0~255之间呈线性分布的噪音)很简单。使用BitmapData.noise()即可。

但要求产生的噪音当中,红色占10%、绿色占10%、蓝色占80%该怎么办?没有现成的方法可以用。但这类噪声却很有用,比如游戏地图的随机生成、制作宇宙的繁星等。

其实很简单!可以使用BitmapData.pixelDissolve()BitmapData.pixelDissolve()是用来溶解像素,制造马赛克的过渡效果的。但它还可以制造噪音!

代码:

package advancedflex.display.images {
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;

public class ImageRandom {

public static function customColorNoise(
src:BitmapData,
sourceRect:Rectangle,
colors:Array,
ratios:Array,
randomSeed:int = 0):int
{
if(colors.length != ratios.length) {
throw new ArgumentError("colors.length != ratios.length.")
}
if(!src) {
throw new ArgumentError("src is null.")
}
var length:int = colors.length;
var s:int = src.width * src.height;
for(var i:int = 0; i < length; i++) {
ratios[i] = s*ratios[i];
}
return customColorNoize2(src, sourceRect, colors, ratios, randomSeed);
}

public static function customColorNoize2(
src:BitmapData,
sourceRect:Rectangle,
colors:Array,
numPixels:Array,
randomSeed:int = 0):int
{
if(colors.length != numPixels.length) {
throw new ArgumentError("colors.length != numPixels.length.")
}
if(!src) {
throw new TypeError("Src must not be null.");
}
var length:int = colors.length;
var point:Point = new Point(sourceRect.x, sourceRect.y)
for(var i:int = 0; i < length; i++) {
randomSeed = src.pixelDissolve(src, sourceRect, point, randomSeed, numPixels[i], colors[i]);
}
return randomSeed;
}
}
}

2007-10-27

奇迹!我的Blog的GooglePR上升为6

简直不敢相信我的眼睛。

昨天,Google PR 还为2,今天居然为6!而且用多种方式查看了,都为6。

奇迹!

2007-10-21

[AS3]位图的色阶控制(2) -- 伽玛校正(Gamma Correction)

[AS3]位图的色阶控制(1) -- 得到色阶

位图调节色阶时,在内部使用的是曲线校正中的伽玛校正。

伽玛校正为调整亮度的方法,它只有一个参数即γ(Gamma)。伽玛校正的变换公式为:

X'=X_max*(x/X_max)^(1/γ)

x'为变换后的亮度。xmax为x的最大值。

γ = 1 x' = x (没有变化)
γ = 0.5 x' = x2(变暗)
γ = 2 x' = √x(变亮)

调整色阶的三个滑条的意思

Plotoshop的调整色阶里有黑,灰,白三个滑条,黑为阴影,白为高亮。从0到黑均为黑色;从白到255均为白色;从黑到白为以灰为中值的伽玛校正。(xb为黑,xg为灰,xw为白)

Actionscript 3.0的实现

实现曲线、伽玛校正等可以使用BitmapData.paletteMap。

三个滑条的值分别为xb、xg、xw (0≤xb≤xg≤xw≤255)。Xmax = xb - xw。当x = xg - xb时,因为想x' / xmax = 0.5,所以

g=( log(Xg-Xb / Xw-Xb) ) / (log(0.5)

var gamma:Number = Math.log((xg - xb) / (xw - xb)) / Math.log(0.5);
var mapR:Array = [], mapG:Array = [], mapB:Array = [];
for(var i:int = 0; i < 256; i++) {
 mapB[i] = i < xb ? 0 : i > xw ? 0xff : 255 * Math.pow((i - xb) / (xw - xb), 1 / gamma);
 mapG[i] = mapB[i] << 8;
 mapR[i] = mapB[i] << 16;
}
image.paletteMap(bmdOrigin, bmd.rect, new Point(), mapR, mapG, mapB);

完整的实现代码:


package bitmap {
 import flash.display.*;
 import flash.filters.*;
 import flash.geom.*;
 import flash.events.Event;

 [SWF(width="256", height="410")]
 public class Histogram3 extends Sprite {
  [Embed(source="023.jpg")]
  private var SampleImage:Class;

  private var dragging:Sprite;
  private var h2pos:Number = 0.5;
  private var h1:Sprite;
  private var h2:Sprite;
  private var h3:Sprite;

  public function Histogram3() {
   stage.scaleMode = "noScale";

   var bmd:BitmapData = Bitmap(addChild(new SampleImage())).bitmapData;

   var s:Sprite = new Sprite();
   addChild(s).y = bmd.height + 10;
   createHistogram(bmd, s);

   s = new Sprite();
   addChild(s).y = bmd.height + 140;
   createHistogram(bmd, s);

   addChild(createSlider()).y = bmd.height + 115;

   var bmdOrigin:BitmapData = bmd.clone();
   addEventListener(
    Event.ENTER_FRAME, 
    function(e:*):void {
     if(dragging) {
      var gamma:Number = Math.log((h2.x - h1.x) / (h3.x - h1.x)) / Math.log(0.5);
      var mapR:Array = [], mapG:Array = [], mapB:Array = [];
      for(var i:int = 0; i < 0x100; i++) {
       mapB[i] = i < h1.x ? 0 : i > h3.x ? 0xff : 255 * Math.pow((i - h1.x) / (h3.x - h1.x), 1 / gamma);
       mapG[i] = mapB[i] << 8;
       mapR[i] = mapB[i] << 16;
      }
      bmd.paletteMap(bmdOrigin, bmd.rect, new Point(), mapR, mapG, mapB);
      
      s.graphics.clear();
      createHistogram(bmd, s);
     }
    }
   );
  }

  // 生成色阶
  private function createHistogram(bmd:BitmapData, s:Sprite):void {
   // 灰度化
   var cmf:ColorMatrixFilter = new ColorMatrixFilter(
    [1 / 3, 1 / 3, 1 / 3, 0, 0, 
     1 / 3, 1 / 3, 1 / 3, 0, 0, 
     1 / 3, 1 / 3, 1 / 3, 0, 0]
   );
   var bmd2:BitmapData = bmd.clone();
   bmd2.applyFilter(bmd2, bmd2.rect, new Point(), cmf);

   // 用threshold来得到颜色分布
   var values:Array = [];
   for(var i:int = 0; i < 0x100; i++) {
    values[i] = bmd2.threshold(bmd2, bmd2.rect, new Point(), "==", 
     i + (i << 8) + (i << 16), 0, 0xffffff, false);
   }
   bmd2.dispose();

   // 画色阶
   var max:int = bmd.width * bmd.height / 50;
   s.graphics.lineStyle(1);
   for(i = 0; i < 0x100; i++) {
    s.graphics.moveTo(i, 100);
    s.graphics.lineTo(i, Math.max(0, 100 - values[i] / max * 100));
   }
  }

  // 生成滑条
  private function createSlider():Sprite {
   // 画滑条可移动的范围
   var slider:Sprite = new Sprite();
   slider.graphics.beginFill(0xffffff);
   slider.graphics.drawRect(0, 0, 256, 10);
   slider.graphics.endFill();
   slider.graphics.lineStyle(1, 0);
   slider.graphics.lineTo(255, 0);
   slider.buttonMode = true;
   slider.useHandCursor = true;

   // 画滑条
   h1 = Sprite(slider.addChild(createButton(0x000000))); h1.x = 0;
   h2 = Sprite(slider.addChild(createButton(0x999999))); h2.x = 128;
   h3 = Sprite(slider.addChild(createButton(0xffffff))); h3.x = 255;

   // mouseDown
   slider.addEventListener("mouseDown", function(e:*):void {
    var localX:Number = slider.globalToLocal(new Point(mouseX, mouseY)).x;

    // 滑动滑条
    var d1:Number = Math.abs(localX - h1.x);
    var d2:Number = Math.abs(localX - h2.x);
    var d3:Number = Math.abs(localX - h3.x);
    var max:Number = Math.min(d1, d2, d3);
    dragging = (max == d1 ? h1 : max == d2 ? h2 : h3);

    // 验证滑条是否超出范围
    var bounds:Rectangle = getDraggableBounds(dragging);
    dragging.x = Math.max(Math.min(localX, bounds.right), bounds.x);
    updateH2(null);

    dragging.startDrag(false, bounds);
   });

   // mouseMove
   stage.addEventListener("mouseMove", updateH2);

   // mouseUp
   stage.addEventListener("mouseUp", function(e:*):void {
    if(dragging) {
     dragging.stopDrag();
     dragging = null;
    }
   });

   return slider;
  }

  // 生成滑条
  private function createButton(color:int):Sprite {
   var s:Sprite = new Sprite();
   s.graphics.lineStyle(1, 0);
   s.graphics.beginFill(color);
   s.graphics.lineTo(5, 8.6);
   s.graphics.lineTo(-5, 8.6);
   s.graphics.endFill();
   return s;
  }

  // 计算滑条的移动范围
  private function getDraggableBounds(s:Sprite):Rectangle {
   if(s == h1) return new Rectangle(0, 0, h3.x - 4, 0);
   if(s == h2) return new Rectangle(h1.x + 2, 0, h3.x - h1.x - 4, 0);
   if(s == h3) return new Rectangle(h1.x + 4, 0, 255 - h1.x - 4, 0);
   return null;
  }

  // 计算灰滑条的移动
  private function updateH2(e:*):void {
   if(dragging && dragging != h2) {
    h2.x = (h3.x - h1.x) * h2pos + h1.x;
    h2.x = Math.max(Math.min(h2.x, h3.x - 2), h1.x + 2);
   }
   else if(dragging == h2){
    h2pos = (h2.x - h1.x) / (h3.x - h1.x);
   }
  }
 }
}

最终效果下载:Histogram2.swf

2007-10-20

[AIR]Adobe AIR Beta 2的安全方面的变化

AIR的更新补丁已经公开了(air_b2_badge_100907.zip : 50.5KB)。它是为了解决之前版本的XSS(cross Site Script)攻击漏洞。最好马上更新。 HTML的安全沙箱也发生了变化。为了对付Javascript的eval()、JSON、innerHTML等的攻击,从Beta 2开始,提供了2种安全沙箱。

第一种安全沙箱叫程序沙箱(Application Sandbox)。它能自由地使用AIR的API,但无法使用外部的Script与eval()。

第二种叫经典沙箱(Classic Sandbox)。它提供与HTML浏览器相同的功能,但无法调用AIR的API。

AIR Beta 2的默认沙箱为程序沙箱。所以几乎所有的AJAX框架都无法正常工作。在这种情况,应该先在经典沙箱里写HTML程序。再在使用AIR的API的地方转换为程序沙箱。最后再添加从经典沙箱调用程序沙箱的处理。使用SandboxBridge,可以使两种沙箱共存。

经典沙箱的指定方法、SandboxBridge的API的具体使用方法等可以参照一个简单的例子(air_htmlsecurity_sample_100107.zip : 64.7KB)。并且在AIR Developer Center(en)里有关联的文章(Building an expense tracker on the new Adobe AIR HTML security model)。

[AS3]RegExp的命名捕获组

命名捕获组为正则表现的捕获组的一种。它利用名字来指定捕获组(当然也可以用下标引用)。它经常使用在层次复杂、难以使用下表的表达式里。

定义命名捕获组使用(?P<名字>)的格式。

比如以下将会定义命名为digits的命名捕获组:

var myPattern:RegExp = /(?P<digits>\d+)/g; //命名捕获组
var str:String = "abc123def";
var result:Array = myPattern.exec(str);
trace(result.digits); //123

再如以下将会定义name与dom两个命名捕获组分别匹配用户名与域名:

var emailPattern:RegExp =
/(?P<name>(\w|[_.¥-])+)@(?P<dom>((\w|-)+))+\.\w{2,4}+/;
var address:String = "bob@example.com";
var result:Array = emailPattern.exec(address);
trace(result.name); // bob
trace(result.dom); // example

注意,命名捕获组不是ECMA-Script定义的。为Actionscript自行扩展的。

2007-10-19

[笑话]2007年BBS上最经典的话

2007年BBS上最经典的71句话[值得你看!] - 文学城: 热点论坛 web.wenxuecity.com
  1. 这个世界上我只相信两个人,一个是我,另一个不是你。
  2. 生活真他妈好玩,因为生活老他妈玩我。  
  3. 好好学习,天天想上!  
  4. 花前月下,不如花钱“日”下。  
  5. 叶子的离开,是因为风的追求还是树的不挽留?   
  6. 有些人就是这样不懂事,你不X他妈,他就不知道你是他爹。    
  7. 你以为我会眼睁睁地看着你去送死吗?我会闭上眼睛的!  
  8. 佛曰:“前世的500次回眸才换来今生的一次擦肩而过”。我宁愿用来世的一次擦肩而过来换得今生的500次回眸。   
  9. 我拿什么整死你的爱人……  
  10. 黑夜给了我一双黑色的眼睛,可我却用它来翻白眼。    
  11. 网络就像是监狱,本来是偷了个钱包进来的,等出去的时候就什么都学会了。    
  12. 女娲日天,后羿射之。    
  13. 兄弟如手足,女人如衣服,谁动我手足,我扒他衣服!    
  14. 我是个演员,一看见漂亮MM眼就圆……    
  15. 上帝把所有人都骗了,因为地狱才是最美的!佛知道真相,所以佛说:“我不入地狱,谁入地狱?”    
  16. 我床上的不知道是谁媳妇,我媳妇不知道在谁的床上!    
  17. 看到你我连食欲都没了,还谈什么性欲?    
  18. 天使之所以会飞,是因为她们把自己看得很轻……    
  19. 我想早恋,但是已经晚了……    
  20. 别人的失败就是我的快乐!    
  21. 天哪!我的衣服又瘦了。    
  22. 生下来的人没有怕死的,怕死的都TM没生下来,所以谁都别TM的装横!    
  23. 现实的社会,毁了我一个做好人的机会!    
  24. 以后不要在我面前说英文,OK?    
  25. 名花虽有主,我来松松土!    
  26. 有钱男子汉,没钱汉子难!    
  27. 我要是妞,早爱上我了……    
  28. 我以为我颓废,原来我报废了!    
  29. 问世间情为何物?圣人答曰:“废物!”    
  30. 我不能给你幸福,但可以给你舒服!    
  31. 思想有多远,你就给我滚多远!    
  32. 流氓不害怕,就怕流氓有文化……    
  33. 客官请自重,小女子只卖身不卖艺。    
  34. 你不能让所有人满意,因为不是所有的人都是人!    
  35. 有事秘书干,没事干秘书。    
  36. 你给我一份爱,我还你一夜情!    
  37. 师太!你就从了老衲吧!    
  38. 我爱你!关你什么事?    
  39. 你的就是我的,我的还是我的!    
  40. 不错!人都是逼出来的。    
  41. 时间就像乳沟,只要挤一挤总还是有的!      
  42. 男人的谎言可以骗女人一夜,女人的谎言可以骗男人一生!     
  43. 鸳鸯戏水,都他妈淹死;比翼双飞,都他妈摔死。    
  44. 承诺就象“CN妈”一样 经常说却很难做得到!    
  45. 我的爱人都叫我第三者!    
  46. 喜欢是淡淡的爱;爱是深深的喜欢!    
  47. 人不猥琐枉少年!    
  48. 我不是一个随便的人,我随便起来不是人……     
  49. 如果你不能给你的女人穿上嫁衣,那么千万别停下你解开她衣扣的手!   
  50. 宁可牺牲中国最后一个处男,决不留下日本任何一个处女!    
  51. 走牛B的路,让去说吧!    
  52. 我不喜欢只和一个女人上很多次床,而是喜欢和很多女人只上一次床。    
  53. 我为兄弟两肋插刀,为女人插兄弟两刀。    
  54. 怀才就像怀孕,时间久了才能让人看出来。    
  55. 想污染一个地方有两种方法:用垃圾,或者用钞票!    
  56. 水能载舟,亦能煮粥!    
  57. 子在川上曰:“有船多好!”    
  58. 骑白马的不一定是王子,可能是唐僧;有翅膀的不一定是天使,也可能是鸟人!     
  59. 大学毕业才明白,原来不是我上大学,而是大学“上”我!    
  60. 我很丑可是我很持久!    
  61. 数钱数到手抽筋,睡觉睡到自然醒!    
  62. 有钱人终成眷属。    
  63. 鸟大了什么林子都有!    
  64. 锄禾“日”当午,弯弓“射”大雕。     
  65. “捷克斯洛伐克”!我叫JACK,我老婆总这样抱怨我。
  66. 只有在大排长龙时,才能真正意识到自己是“龙的传人”。

2007-10-14

[AS3]位图的色阶控制(1) -- 得到色阶

色阶为位图的颜色分布的图。做过图形处理的应该很熟悉。

比如下图:上面为原图,下面为色阶。

Historgram

得到方法:

  1. 灰色化。把各个通道求平均。用ColorMatrixFilter即可。
  2. 用threshold来得到颜色分布。threshold的返回值为匹配的像素的个数。

代码:


package {
    import flash.display.*;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.Point;

    public class TestBitmap extends Sprite {
        [Embed(source="023.jpg")]
        private var SampleImage:Class;

        public function TestBitmap() {
            var bmd:BitmapData = Bitmap(addChild(new SampleImage())).bitmapData;
            var s:Sprite = new Sprite();
            createHistogram(bmd,s);
            addChild(s).y = bmd.height + 10;
        }

        //生成色阶
        private function createHistogram(bmd:BitmapData, s:Sprite):void {
            //灰度画
            var cmf:ColorMatrixFilter = new ColorMatrixFilter(
                [1 / 3, 1 / 3, 1 / 3, 0, 0, 
                 1 / 3, 1 / 3, 1 / 3, 0, 0, 
                 1 / 3, 1 / 3, 1 / 3, 0, 0]
            );
            var bmd2:BitmapData = bmd.clone();
            bmd2.applyFilter(bmd2, bmd2.rect, new Point(), cmf);

            //用threshold来得到颜色分布
            var values:Array = [];
            for(var i:int = 0; i < 0x256; i++) {
                values[i] = bmd2.threshold(bmd2, bmd2.rect, new Point(), "==", i, 0, 0xff, false);
            }
            bmd2.dispose();

            //画色阶
            var max:int = bmd.width * bmd.height / 50;
            s.graphics.lineStyle(1);
            for(i = 0; i < 256; i++) {
                s.graphics.moveTo(i, 100);
                s.graphics.lineTo(i, Math.max(0, 100 - values[i] / max * 100));
            }
        }
    }
}

我的附件

我的附件。

[AS3]位图过度之模板过度

先来看效果:

它使用的模板为:

运行原理很简单,主要是运用阈值,再设置原图的Alpha通道。详细看源码

源码下载BitmapPatternTween.fla

2007-10-09

Adobe AIR的电子署名

AIR Beta 2以后,在打包时必须制作电子署名。电子署名的目的为:

  1. 确认包未被修改(比如说被绑定病毒)
  2. 确认包的创建者。

如果未署名,将会生成扩展名为airi的文件,这个如果不用adt等来署名的话,将无法安装到AIR运行环境。

署名可以使用CA发行的或者自己的署名的证明书。用自己的署名的证明书的话无法用于以上的确认包的创建者的目的。

注意,电子署名并不保证程序能够正常运行。并且,因为现在为Beta,所以并不能保证电子署名本身功能的正确性。

自己的署名的证明书的制作

自己的署名的证明书可以用 Flex Builder 3 Beta 2,Flash CS3/Dreamweaver CS3 的 AIR Beta 2用的扩展插件来制作。注意,千万别忘了密码

用Flex Builder 3 Beta 2来制作

执行Export向导,当显示"Digital Signature"的画面时,点"Create..."按钮。再输入署名,密码,生成的文件,点OK。注意在名字里可以使用的只有英数字。

用Flash CS3来制作

选择AIR->Application & Installer Settings打开设置窗口,并且确认 Sign the AIR file with a digital certificate 是选中的。再点击"Digital Signature"右边的 "Change..."按钮。这将会打开设定署名的窗口。以后与Flex Builder相同。(可以选择1024 Bit与2048 Bit)

用Dreamweaver CS3来制作

选择Site->AIR Application Settings...打开设置窗口。再点击"Digital signature"右边的"Set..."。这将会打开设定署名的窗口。以后与Flash CS3相同。

2007-10-03

新的RIA制作工具 - Thermo

Thermo是为了提高RIA的UI设计的工具。

ThermoMain

Thermo的功能如下(预定):

  1. 用Photoshop, Illustrator, Fireworks来设计画面。
  2. 创建的文件可以直接用Thermo来打开,并用它的绘画工具来设计画面。
  3. 对画面设计添加交互功能。
  4. 制定过度与特效。
  5. 设定测试数据来运行与测试。
  6. 输出MXML。

有一种Photoshop, Illustrator, Fireworks为平面设计者,Thermo为交互设计者的工具的感觉。因为可以与FlexBuilder的文件共享,所以RIA的开发效率会大大提高。

Demo的图片等详细参见Adobe Lab(Thermo@Labs

2007-10-02

Spry 1.6 与 AIR Extension for Flash & Dreamweaver CS3

Spry 1.6 Pre-realse 发布了!Spry Framework 是为Ajax开发的轻量级的UI等的库。它可以高校地开发出强壮的Ajax网页。 Spry Framework 的 Dreamweaver CS3 的升级也公开了。(Spry Prerelease 1.6 Download@Labs)变更已经写在上面了,大家可以去看一看。(Spry Change Log@Labs)Log也更新了。(Spry framework for Ajax@Labs

并且AIR Beta 2 的Dreamweaver CS3 与 Flash CS3功能扩展插件也发布了。均支持以下环境

  • Windows XP SP2
  • Windows Vista
  • Mac OS 10.4.x (Intel or PPC)

注意,必须先卸载以前的版本在安装。

Flash Player 10的特大新闻!

在US的MAX大会上,公布了Code名为Astro的Flash Player 10的部分新功能如下:

新的Text Layout 渲染引擎

Astro将会添加新的Text Layout 渲染引擎。有了这个就有可能能够做到类似于HTML的表现能力的Text。这个功能有可能会在Flash Player 9的新版本中添加。

3D

终于来了!

Flash 的 MovieClip将会能够在3D空间内操作了。虽然Demo是很简单的效果,离真正的3D还有一定的距离,但表现将会有大幅度的提升。

自定义滤镜,混合模式,特效

将会可以自己开发滤镜等了。这些的制作将会使用已发布的Adobe Image Foundation (AIF) Toolkit。AIF Toolkit虽然为预览版,但已经能够下载了。会C,OpenGL的开发者可以试一试。(Adobe Image Foundation (AIF) Toolkit@Labs

看来Flash Player 与 Silverlight的大战开始了!

2007-10-01

Flex 3 beta 2

Flex 3 Beta 2 在Adobe Lab 发布了。详细参见(Adobe FlexBuilder@Labs, Adobe Flex SDK@Labs

根据Flex 3 Planning的最新信息,Flex 3 的时间表如下:

  • April 9, 2007 M1 Release (Alpha)
  • June 11, 2007 M2 Release (Beta 1)
  • October M3 Release (Beta 2) - Feature Complete
  • Late 2007 M4 - Release Candidate
  • Early 2008 Final Release

本次的内部版本为M3,即第三个测试版本。功能已经完全实装了。在今年内将发布RC版本,即M4。

使用CrossDomain RSL时,必须使用一起发布的Flash Player(9.0.60.235)。这个Flash Player 为Beta版。

Flex Skin Design Extensions

为CS3的产品的Flex 3 Skin制作的导入的功能扩展也发布了。目前的版本为Pre-release。提供了Photoshop, Illustrator, Flash, Fireworks的功能扩展。

下载地址(Flex Skin Design Extensions@Labs Downloads