2011-12-08 19 views
0

好了,我已經試過作爲下同航代碼這個簡單的過濾器:爲什麼Pixel Bender過濾器在Toolkit中的表現與Flex/Air應用中的表現不同?

<languageVersion : 1.0;> 

kernel NewFilter 
< namespace : "Your Namespace"; 
    vendor : "Your Vendor"; 
    version : 1; 
    description : "your description"; 
> 
{ 
    input image4 src; 
    output pixel4 dst; 

    void 
    evaluatePixel() 
    { 
     pixel4 cPix = sampleNearest(src,outCoord()); 
     pixel3 RGB = cPix .rgb; 
     float r = RGB.r; 
     float g = RGB.g; 
     float b = RGB.b; 
     //float minVal = min(r, g); 
     dst = pixel4(r, g, b, 1); 
    } 
} 

事實證明,如果我取消這條線float minVal = min(r, g);,我沒有得到原始圖片更多,但這: Result

取而代之的是: Original

如果有人可以解釋這樣對我......我會非常感激......

//------------------------------------------------------------------ 
//------------------- ORIGINAL POST -------------------------------- 

我正在嘗試爲flex應用製作像素彎曲濾鏡,它將輸入圖像的色調值的選定範圍更改爲定義的新色調值。 我在Pixel bender Toolkit中製作了這樣的濾鏡,並且它給出了令人滿意的結果。

這是該過濾器的代碼:

<languageVersion : 1.0;> 

kernel ColorChange 
< namespace : "Your Namespace"; 
    vendor : "Your Vendor"; 
    version : 1; 
    description : "your description"; 
> 
{ 
    input image4 src; 
    output pixel4 dst; 

    parameter float HUE 
    < 
     minValue: 0.; 
     maxValue: 359.9; 
     defaultValue: 0.; 
    >; 
    parameter float SAT 
    < 
     minValue: -1.; 
     maxValue: 1.; 
     defaultValue: 0.; 
    >; 
    parameter float VAL 
    < 
     minValue: -1.; 
     maxValue: 1.; 
     defaultValue: 0.; 
    >; 

    parameter float MIN_RANGE 
    < 
     minValue: 0.; 
     maxValue: 360.; 
     defaultValue: 0.; 
    >; 

    parameter float MAX_RANGE 
    < 
     minValue: 0.; 
     maxValue: 360.; 
     defaultValue: 360.; 
    >; 

    void 
    evaluatePixel() 
    { 
     pixel4 cPix = sample(src,outCoord()); 
     pixel3 RGB = cPix.rgb; 
     float3 HSV; 
     //-------------------------------------------------------------- 
     // CONVERT RGB TO HSV 
     //-------------------------------------------------------------- 
     pixel1 r = RGB.r; 
     pixel1 g = RGB.g; 
     pixel1 b = RGB.b; 

     pixel1 minVal = min(min(r, g), b); 
     pixel1 maxVal = max(max(r, g), b); 
     pixel1 delta = maxVal - minVal; 
     HSV[2] = maxVal; 
     if (maxVal == 0.) { 
      HSV[0] = 0.; 
      HSV[1] = 0.; 
     } 
     else 
     { 
      HSV[1] = delta/maxVal; 
     } 

     if(r == maxVal) 
      HSV[0] = (g-b)/delta; 
     else if(g == maxVal) 
      HSV[0] = 2. + (b-r)/delta; 
     else 
      HSV[0] = 4. + (r-g)/delta; 

     HSV[0] *= 60.; 
     if(HSV[0] <0.) 
      HSV[0] += 360.; 

     //-------------------------------------------------------------- 
     // FILTER RANGE OF HUE 
     //-------------------------------------------------------------- 
     if((HSV[0] < MIN_RANGE) || (HSV[0] > MAX_RANGE)) 
     { 
      dst = cPix; 
     } 
     else 
     { 
      //-------------------------------------------------------------- 
      // CHNAGE HSV 
      //-------------------------------------------------------------- 
      float hH = HUE; 
      float sS = SAT; 
      float vV = VAL; 
      HSV[0] = HUE; 
      HSV[1] += SAT; 
      if(HSV[1] > 1.) 
       HSV[1] = 1.; 
      else if(HSV[1] < 0.) 
       HSV[1] = 0.; 
      HSV[2] += VAL; 
       if(HSV[2] > 1.) 
        HSV[2] = 1.; 
       else if(HSV[2] < 0.) 
        HSV[2] = 0.; 
      //---------------------------------------------------------------------- 
      // CONVERT HSV TO RGB 
      //---------------------------------------------------------------------- 
      float h = HSV[0];///360.; 
      float s = HSV[1];///100. * 255.; 
      float v = HSV[2];///100. * 255.; 

      if (s == 0.) { 
       RGB.r = v; 
       RGB.g = v; 
       RGB.b = v; 
      } else { 
       h = h/60.; 
       int var_i = int(floor(h)); 
       float f = h - float(var_i); 
       float p = v * (1.-s); 
       float q = v * (1.-s*f); 
       float t = v * (1.-s*(1.-f)); 
       if (var_i == 0) { 
        RGB.r = v; 
        RGB.g = t; 
        RGB.b = p; 
       } 
       else if (var_i == 1) { 
        RGB.r = q; 
        RGB.g = v; 
        RGB.b = p; 
       } 
       else if (var_i == 2) { 
        RGB.r = p; 
        RGB.g = v; 
        RGB.b = t; 
       } 
       else if (var_i == 3) { 
        RGB.r = p; 
        RGB.g = q; 
        RGB.b = v; 
       } 
       else if (var_i == 4) { 
        RGB.r = t; 
        RGB.g = p; 
        RGB.b = v; 
       } 
       else { 
        RGB.r = v; 
        RGB.g = p; 
        RGB.b = q; 
       } 
      } 
      dst = pixel4(RGB.r, RGB.g, RGB.b, 1); 
     } 
    } 
} 

所以,原理很簡單,轉換每個像素到HSV色彩空間,檢查是否色調落在選定的範圍之間,如果它不改變它的色調來定義一個並轉換回RGB。

問題是,當在Air應用程序中使用時,我得不到相同的結果,從僅使用過濾器的默認參數的角度開始。

這是AIR應用程序的代碼:

<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         width="1400" height="800" backgroundAlpha="0.0" xmlns:mx="library://ns.adobe.com/flex/mx" 
         creationComplete="windowedapplication1_creationCompleteHandler(event)"> 
    <fx:Declarations> 
     <!-- Place non-visual elements (e.g., services, value objects) here --> 
    </fx:Declarations> 

    <fx:Script> 
     <![CDATA[ 
      import mx.events.ColorPickerEvent; 
      import mx.events.FlexEvent; 

      import spark.filters.ShaderFilter; 
      import spark.utils.BitmapUtil; 

      [Embed(source="myFilter.pbj", mimeType="application/octet-stream")] 
      private var MyBender:Class; 

      private var shader:Shader = new Shader(); 
      private var shaderJob:ShaderJob; 
      private var shaderResult:BitmapData; 


      private function filter():void 
      {      
       // Configure desired input parameters of shader. 
       shader.data.src.input = originalImage.bitmapData; 

//    shader.data.HUE.value = [H_slider.value]; 
//    shader.data.SAT.value = [S_slider.value]; 
//    shader.data.VAL.value = [V_slider.value]; 
//    shader.data.MAX_RANGE.value = [H_max_slider.value]; 
//    shader.data.MIN_RANGE.value = [H_min_slider.value]; 

       shaderJob = new ShaderJob(shader, shaderResult); 
       shaderJob.start(true); 
       bendedImage.source = new Bitmap(shaderResult); 
      } 

      private function windowedapplication1_creationCompleteHandler(event:FlexEvent):void 
      { 
       // Create new shader instance and initialize with embedded byte code. 
       shader = new Shader(new MyBender()); 
       shaderResult = new BitmapData(originalImage.width, originalImage.height); 
       filter(); 
      } 

     ]]> 
    </fx:Script> 
    <s:HGroup width="100%"> 
     <s:Group id="originalGroup" width="100%"> 
      <s:Image id="originalImage" source="mandelbrot.png"/> 
     </s:Group> 
     <s:Group id="bendedGroup" width="100%"> 
      <s:SWFLoader id="bendedImage" source="mandelbrot.png" /> 
      <s:HSlider id="H_slider" minimum="0" maximum="359.9" stepSize="0.1" value="0" change="filter()" width="500" toolTip="HUE"/> 
      <s:HSlider id="S_slider" minimum="-1" maximum="1" stepSize="0.1" value="0" y="20" change="filter()" width="500" toolTip="SAT"/> 
      <s:HSlider id="V_slider" minimum="-1" maximum="1" stepSize="0.1" value="0" y="40" change="filter()" width="500" toolTip="VAL"/> 
      <s:HSlider id="H_max_slider" minimum="0" maximum="360" stepSize="0.1" value="360" y="60" change="filter()" width="500" toolTip="HUE MAX"/> 
      <s:HSlider id="H_min_slider" minimum="0" maximum="360" stepSize="0.1" value="0" y="80" change="filter()" width="500" toolTip="HUE MIN"/> 
     </s:Group> 
    </s:HGroup> 
</s:WindowedApplication> 

所以,在AIR應用程序使用默認參數應用PixelBender濾波器產生這樣的:

http://i.stack.imgur.com/UyoZR.png

但在Pixel Bender工具包我看到這個具有相同的參數:

http://i.imgur.com/LNnCi.png

更改應用程序中的HUE_MAX滑塊(綁定到MAX_RANGE過濾器參數),它不會平滑過濾掉HUE值,而是在HUE_MAX = 59.9時進行閾值處理,其中較低的值看起來不應用過濾器,並且在HUE_MAX =長相299.9,其中60和299.9之間是這樣的:

http://i.stack.imgur.com/5kePu.png(對不起,新用戶)

任何想法,我究竟做錯了什麼?

+0

它是因爲我已經用PB很長一段時間時,你不應該在這種情況下使用ShaderFilter問題就解決了,但是?我在代碼中看到了導入,但從未使用。 – RIAstar

回答

2

min函數確實參數,我不能解釋。 但使用

pixel1 minVal = r; 
if(g < minVal) 
minVal = g; 
if(b < minVal) 
minVal = b; 

,而不是

pixel1 minVal = min(min(r, g), b); 
0

你的PB代碼中有很多浮點比較。行這樣的:

if (maxVal == 0.) 

是extrenely易患舍入誤差。我建議使用這樣的事情,而不是:

if (abs(maxVal) < epsilon) 
+0

不幸的是,這並沒有幫助。但與這些閾值和這行代碼奇怪的巧合:'HSV [0] * = 60。如果(HSV [0] <0) HSV [0] + = 360。 ((HSV [0] MAX_RANGE))'...因爲閾值在60(1 * 60)和300(-60 + 360) – Piaf

0

你的AS代碼有設置註釋掉的參數值的行。你可以嘗試將它們重新評論並將其值設置爲默認值。放入PB文件的默認值不是由運行時自動設置的,它們只是提示用戶界面。

相關問題