关于Pixel Bender

Pixel Bender介绍

 

下面是摘自Adobe官方文档 Adobe Pixel Bender Developer’s Guide对Pixel Bender的介绍:

 

The Adobe Pixel Bender technology delivers a common image and video processing infrastructure which provides automatic runtime optimization on heterogeneous hardware. You can use the Pixel Bender kernel language to implement image processing algorithms (filters or effects) in a hardware-independent manner.

 

翻译(翻得烂,建议大家还是看原文吧):

Pixel Bender是Adobe开发的一套针对图像、视频处理的底层框架,可以依赖于多种不同硬件来进行优化加速。使用Pixel Bender,需要用专门的语言Pixel Bender kernel来编写图像处理逻辑(比如自定义滤镜或者特效)。

 

Pixel Bender development offers many advantages:

  1. Low learning curve Pixel Bender offers a small number of tools that are sufficient to write complex image-processing algorithms. Learning Pixel Bender is easier than learning C/C++ and each application’s plug-in SDK. You do not need to know any graphics shading language or multi-threading APIs.

  2. Parallel processing Pixel Bender allows the same filter to run efficiently on different GPU and CPU architectures, including multi-core and multiprocessor systems. It delivers excellent image processing performance in Adobe products.

  3. Supports all bit-depths The same kernel runs in 8-bit/16-bit/32-bit within the application.

  4. Support by multiple Adobe applications Pixel Bender is integrated with multiple Adobe applications. It allows you to develop filters that are portable among various Adobe products. There is an active Pixel Bender Exchange where developers share their filters.

 

翻译: 

Pixel Bender的优点:

  1. 容易学习。Pixel Bender提供了一些功能齐全的工具,可用于编写复杂的图像处理逻辑。学习简单,使用类似C++的语法,结构简单,而且不要求开发人员对图像shading language基础或多线程的API有所了解。
  2. 在8-bit/16-bit/32-bit的机器上都可运行。
  3. 多款Adobe产品支持(Photoshop、After Effect、Flash)。(“在一定规范下” -- 译者注)开发人员可编写一款各产品通用的滤镜。在Pixel Bender Exchange上,有很多开发人员还分享出来他们编写的滤镜。

 

Pixel Bender技术可应用于 Photoshop、After Effect、Flash等Adobe产品,但对于Flash的应用,会有比较大的限制:

  1. 只能应用使用ActionScript 3.0编写的swf,且使用Flash Player 10.0之后的版本。
  2. 除了if/else,无法使用任何形式的循环和其他程序流控制。
  3. 不支持数组。
  4. 不允许自定义函数或库。
  5. 不允许使用region functions。
  6. 不允许使用dependent values
  7. non-constant indices into vector values
  8. 无法调用GPU资源(至少到目前2010年10月份为止是这样)

 

=_=|||
确实是很多限制,一开始想使用Pixel Bender对Flash展示层做大规模优化的幻想破灭了。

 

 

Pixel Bender的应用场合

 

对于Pixel Bender的应用,主要有下面几种:

  • 自定义滤镜
  • 填充:即某块区域的绘制完全由Pixel Bender来生成,比如可用于制作游戏中特效。
  • Blend Mode
  • 32位的浮点运算(这一点是比较神奇,但不在谈论之列,后续可以再另外分享)

 

但是,有时候使用Pixel Bender写的滤镜效率并没有想象中那么高。下面有个例子:

首先,大家可以先看一下StackOverFlow上的这个贴:using PixelBender to double the size of a bitmap.

提问者提出了一个问题:

同样是将一张图片的尺寸放大一倍,使用Pixel Bender,和使用AS3自带的库类BitmapData.draw()方法,在执行时间上分别是前者是后者的4倍。

后面就有人回答:

在这个场景中,Pixel Bender代码对比的对象,其实是player底层代码(因为想BitmapData这种类肯定是player底层实现的),而不是ActionScript 3。所以对于一些player原生支持的功能,如果用Pixel Bender重新实现一遍,并不会快于player(否则,Adobe的工程师们早就利用Pixel Bender的技术去提高Flash Player的执行效率了)。

 

因此,Pixel Bender的效率应该是高于(远远高于)使用ActionScript直接控制像素;但在同一程序逻辑下,不会高于player本身的效率。

那么,Pixel Bender的应用场合应该是:当需要写一些自定义、灵活的滤镜效果,这时候就应该使用它。它是对那些效率高但不灵活的滤镜效果(player自带的)和效率低但很灵活的滤镜效果(AS3写)的一个折衷。

 

 

Pixel Bender与Flash结合的运行方式 

 

在Flash Player 10里集成了有一个Pixel Bender runtime,解释运行由Pixel Bender toolkit生成了pbj文件。Pixel Bender runtime之于pbj,就相当于Flash Player之于swf。

Pixel Bender runtime是使用多线程的,不会和player使用同一线程。在多核的机器上,可以使用多个cpu资源,所以在效率上是有很大提高的,而且不会导致Flash UI的阻塞。所以,我猜上一节中的案例应该是在单核环境中的。如果在多核环境中,Pixel Bender多个线程的执行速度应该会高于player一个线程的速度。

目前版本的Pixel Bender runtime(2010年10月份)是无法支持GPU加速的。那既然Pixel Bender Toolkit有GPU模式,那为什么不把这个功能集成到Flash Player中呢?这篇文章(Adobe Pixel Bender in Flash Player 10 Beta)有做介绍。作者是Flash Player的工程师,诉尽苦衷,主要考虑的还是那两个方面:1.平台兼容性;2.Flash Player的大小。

 

 

 

 

 参考资料

 

单色化滤镜的代码(MonochromeFilter.pbk)

<languageVersion: 1.0;>

kernel MonochromeFilter
<
    namespace: "com.tencent.qqshow";
    vendor: "Tencent";
    version: 1;
    description: "Monochrome Filter";
>
{
    parameter pixel4 color
    <
        defaultValue: float4(0.5, 0.5, 0.5, 1);
    >;
    
    output pixel4 dst;
    
    input image4 src;    

    void evaluatePixel()
    {
        pixel4 c = sampleNearest(src, outCoord());
        pixel4 target = c;
        
        //caculate the 256 grey level
        float gl = c.r * 0.3086 + c.g * 0.6094 + c.b * 0.082;
                
        if(gl < 0.5)
        {
            target.r = color.r * gl * 2.0;
            target.g = color.g * gl * 2.0;
            target.b = color.b * gl * 2.0;
        }
        else
        {
            target.r = color.r + (1.0 - color.r) * (gl - 0.5) * 2.0;
            target.g = color.g + (1.0 - color.g) * (gl - 0.5) * 2.0;
            target.b = color.b + (1.0 - color.b) * (gl - 0.5) * 2.0;
        }
        
        dst = target;
    }
}

Flash wmode=transparent 与TextField不兼容的BUG

在FireFox下,当加载swf的那段<object>或<embed>里的wmode="opaque"或wmode="transparent"时,Flex TextInput和TextArea无法输入正确中文。详见此帖

 
经Google之后,很多地方说
“由Flex编译生成的那段JS,可以保证在FireFox的情况下,TextInput和TextArea可以正常输入。”
其实是错的。。。
那段脚本只是用于做Flash Player版本检测和提供deep-link功能(见官方帮助"About the wrapper")
 
在这篇文章Flash wmode=transparent breaks textinput field中,Adobe的一个工程师(John Dowdell)对这个问题作出了回应:
Asking the browser to do stuff is hard, because they all have fringe behavior.
In this case we’re asking the browser to accept plugin input directly into its own compositing stack, instead of blasting direct to screen.
Weirdest WMODE problem I’ve seen has been one where asking the browser to print the webpage would print the SWF upside down. Others have had accessibility differences.
If it’s just in Player, we can fix it ourselves. But if it’s in the communication with the browsers, it’s harder.
I’m sorry you lost time on it though. :(
 
jd/adobe
 
 
有个比较山寨的解决方法:然后一个比较山寨的方法,就是利用js监听用户的输入,然后通过js把用户的输入发给swf。 

JSTextReader

 

 

另一个山寨的解决方法,也是和JS配合。自定义了一个文本输入组件,焦点进入该组件时,利用JS在组件对应位置弹出一个对应的HTML的输入框。

http://nwhy.org/flash-swfinputs-solving-mozilla-transparent-mode.html

 

SWF加密

最近帮编辑部那边做了某款网游的NPC查询器,技术上没啥好说,挺简单的一个东西。但放上网站第二天就给别人盗用了(囧。。。),直接用未破解的swf,然后再我们的水印上盖一层自己的戳……

但swf的加密一直是软肋。找了几个加密软件,都不太好用,不是加密后仍然可以被破解,就是加密后损坏了swf本身。
值得说一下的是doswf,对简单的swf加密效果还是不错,可以有几种加密效果搭配选择,但是是收费的。而且后来发现我的swf加密后,按钮都无法点击了。
有两种简单的初级加密方法:
  1. 防盗用:URL判断。只要不是在指定域名内,可令程序无法运行。
  2. 保护源代码:代码混淆。将变量名、方法名都变成随机字符串。
  3. 保护加载资源的资源:ByteArray加密。将加载的资源先进行二进制级别加密,以ByteArray形式加载到swf后,再解密。这样可以防止在浏览器缓存里直接获取加载的资源。
  4. 防破解:加壳。同方法3,只是把资源文件变成了swf:把主swf进行二进制级别加密(不再是swf格式),再创建一个专门用于加载、解密主swf的swf,这样就可以起到保护主swf的作用了。
以上方法中:
  1. 方法1:只要破解了swf,得到源代码,就可以修改指定的域名,因此最好与方法2同时使用。
  2. 方法2无法保护加载的资源。
  3. 方法3和方法4,因为解密算法是以明文写在代码里的,因此只要破解了代码,就可以找到解密算法。
另外,现在的swf加密的基础都是基于swf文件格式,这里可以下载相关的pdf,有空研究一下。