2010-01-08 11 views
1

Supposons que j'ai converti un fichier d'image vectorielle (.AI/.SVG) en .SWF pour faciliter l'importation dynamique en tant que source d'une image dans Flex.Flex - Comment compter les couleurs dans le fichier vectoriel .SWF

Pour compter les couleurs maintenant, je dois créer une "nouvelle BitMap", puis ".draw()" et parcourir tous les pixels et utiliser ".getPixel()" pour récupérer la couleur.

Malheureusement, en raison de l'anti-aliasing, cela semble retourner plusieurs couleurs de plus que ce qui est réellement utilisé pour dessiner l'image (disons, un logo noir).

Existe-t-il une meilleure alternative à cela dans Flex? Essayez d'utiliser ConvolutionFilter pour affiner l'image vectorielle d'origine.

+0

peut-il être une étape de pré-processus? – jedierikb

+0

Oui, je suppose que ça peut l'être. – Eric

Répondre

1

J'ai une solution, mais ce n'est peut-être pas la meilleure solution. Fondamentalement, je suis juste en boucle à travers les octets du swf en utilisant as3swf et en cherchant des définitions de forme puis en arrivant aux remplissages. De là, je pousse les couleurs (les pleins et les couleurs trouvés dans les dégradés) dans un tableau. Comme il peut y avoir des doublons, je les supprime à la fin.

Voici le code:

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

Assez étonnamment, c'était en réalité beaucoup plus rapide que le traitement de chaque pixel dans le tableau BitMapData. Merci pour la suggestion! – Eric

0

Vous devrez peut-être ajuster la matrice de filtre pour obtenir les bonnes valeurs pour aiguiser l'anti-aliasing. Ensuite, exécutez la méthode BitmapData.draw() sur l'image pour parcourir les pixels et les données de pixels. L'affûtage du vecteur d'origine permettra de détecter de très petites zones colorées; Si vous affinez l'objet Bitmap après draw(), ces couleurs peuvent être rendues légèrement différentes de l'original.

1

Pour se débarrasser du vecteur anti-aliasing, vous pouvez définir la propriété stage.quality à StageQuality.LOW avant de tirer dans un BitmapData, il pourrait faire l'affaire .

Ce sera sûrement plus complexe, mais pour accélérer votre algorithme, PixelBender ou Alchemy pourraient probablement faire l'affaire.

+0

Marqué cela comme une réponse aussi, car cela fonctionne. Tenter d'atténuer le problème lorsque l'utilisateur voit le changement de qualité pendant que les couleurs sont comptées, puis inversé. Merci beaucoup! – Eric

Questions connexes