2010-01-08 28 views
1

假設我已將矢量圖像文件(.AI/.SVG)轉換爲.SWF,以便作爲Flex中圖像的來源進行動態導入。現在要計算顏色,我必須創建一個「新的BitMap」,然後「.draw()」並迭代所有像素,並使用「.getPixel()」來檢索顏色。Flex - 如何計算.SWF矢量文件中的顏色

不幸的是,由於抗鋸齒,這似乎返回比實際用於繪製圖像(比如黑色標誌)更多的顏色。

有沒有更好的選擇在Flex中做到這一點?

+0

這是一個預處理步驟嗎? – jedierikb

+0

是的,我想可以。 – Eric

回答

1

我有一個解決方案,但它可能不是最好的。 基本上我只是使用as3swf來循環讀取swf的字節,並尋找形狀定義,然後進行填充。從那裏,我將顏色(實心填充和漸變中發現的顏色)推入數組中。由於可能有重複,所以我最後刪除它們。

下面的代碼:

import com.codeazur.as3swf.*; 
import com.codeazur.as3swf.tags.*; 

var colors:Array = []; 
var colorsNum:int = 0; 
var request:URLRequest = new URLRequest("plank.swf"); 
var loader:URLLoader = new URLLoader(); 
loader.dataFormat = URLLoaderDataFormat.BINARY; 
loader.addEventListener(Event.COMPLETE, completeHandler); 
loader.load(request); 

function completeHandler(e:Event):void { 
    var swf:SWF = new SWF(URLLoader(e.target).data as ByteArray); 
    var tagsNum:int = swf.tags.length; 
    for(var i:int = 0 ; i < tagsNum ; i++){ 
     if(swf.tags[i].name.substr(0,11) == 'DefineShape'){ 
      var fillStylesNum:int = TagDefineShape4(swf.tags[i]).shapes.fillStyles.length; 
      if(fillStylesNum > 0){ 
       for(var j:int = 0 ; j < fillStylesNum ; j++){ 
        if(TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].gradient){ 
         var recordsNum:int = TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].gradient.records.length; 
         for(var k:int = 0 ; k < recordsNum; k++){} 
          colors.push(TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].gradient.records[k].color) 
        }else{ 
         colors.push(TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].rgb); 
        } 
       } 
      } 
     } 
    } 
    colors.sort(Array.NUMERIC); 
    removeDuplicates(colors); 
    trace('numColors: ' + colors.length + '\ncolors: ' + colors); 
} 
function removeDuplicates(array:Array):Array{ 
    var length:int = array.length; 
    var i:int, j:int; 
    var newLength:int = 1; 

    for(i=1; i< length; i++){ 

     for(j=0; j< newLength ; j++) 
     { 

      if(array[i] == array[j]) 
      break; 
     } 
     if (j==newLength) 
      array[newLength++] = array[i]; 
    } 
    array.length = newLength; 
    return array; 
} 

HTH

+0

令人驚訝的是,這實際上比處理BitMapData數組中的每個像素要快得多。感謝您的建議! – Eric

0

嘗試使用ConvolutionFilter來銳化原始矢量圖像。您可能需要調整濾波器矩陣以獲得正確的值以清除抗鋸齒。然後在圖像上執行BitmapData.draw()方法以遍歷像素和像素數據。銳化原始矢量將允許檢測非常小的彩色區域;如果在draw()之後銳化Bitmap對象,則可能會將這些小區域顏色呈現爲與原始顏色略微不同的顏色。

1

爲了擺脫矢量抗鋸齒的,你可以設置stage.quality屬性StageQuality.LOW在一個BitmapData繪製它之前,它可能做的伎倆。

它肯定會更復雜一些,但爲了加速算法,你可能會得到PixelBender或Alchemy來完成這項工作。

+0

也將其標記爲答案,因爲它確實有效。試圖減輕用戶在計數顏色時看到質量變化的問題,然後逆轉回去。 謝謝! – Eric