2009-03-03 7 views
3

J'essaie d'écrire quelque chose dans mon application Flex 3 avec actionscript qui va prendre une image et quand un utilisateur clique sur un bouton, il va supprimer tous les pixels blancs (ish) et les convertir en transparent, je dis blanc (ish) parce que j'ai essayé exactement blanc, mais je reçois beaucoup d'artefacts sur les bords. J'ai obtenu un peu près en utilisant le code suivant:Flex/Actionscript Blanc à Transparent

targetBitmapData.threshold(sourceBitmapData, sourceBitmapData.rect, new Point(0,0), ">=", 0xFFf7f0f2, 0x00FFFFFF, 0xFFFFFFFF, true); 

Cependant, il est aussi rouge ou jaune disparaître. Pourquoi ça fait ça? Je ne suis pas sûr de savoir comment faire ce travail. Y at-il une autre fonction qui convient mieux à mes besoins?

+0

N'est-ce pas RGBA, vous semblez faire ARGB dans vos masques? – grapefrukt

Répondre

1

Un ami et moi essayions de le faire il y a un certain temps pour un projet, et avons trouvé que l'écriture d'une méthode en ligne qui le fait en ActionScript est incroyablement lente. Vous devez scanner chaque pixel et faire un calcul contre celui-ci, mais le faire avec PixelBender s'est avéré être ultra rapide (si vous pouvez utiliser Flash 10, sinon vous êtes coincé avec AS lent).

Le code bender pixel ressemble:

input image4 src; 
output float4 dst; 

// How close of a match you want 
parameter float threshold 
< 
    minValue:  0.0; 
    maxValue:  1.0; 
    defaultValue: 0.4; 
>; 

// Color you are matching against. 
parameter float3 color 
< 
    defaultValue: float3(1.0, 1.0, 1.0); 
>; 

void evaluatePixel() 
{ 
    float4 current = sampleNearest(src, outCoord()); 
    dst = float4((distance(current.rgb, color) < threshold) ? 0.0 : current); 
} 

Si vous devez le faire en tant que vous pouvez utiliser quelque chose comme:

function threshold(source:BitmapData, dest:BitmapData, color:uint, threshold:Number) { 
    dest.lock(); 

    var x:uint, y:uint; 
    for (y = 0; y < source.height; y++) { 
    for (x = 0; x < source.width; x++) { 
     var c1:uint = source.getPixel(x, y); 
     var c2:uint = color; 
     var rx:uint = Math.abs(((c1 & 0xff0000) >> 16) - ((c2 & 0xff0000) >> 16)); 
     var gx:uint = Math.abs(((c1 & 0xff00) >> 8) - ((c2 & 0xff00) >> 8)); 
     var bx:uint = Math.abs((c1 & 0xff) - (c2 & 0xff)); 

     var dist = Math.sqrt(rx*rx + gx*gx + bx*bx); 

     if (dist <= threshold) 
     dest.setPixel(x, y, 0x00ffffff); 
     else 
     dest.setPixel(x, y, c1); 
    } 
    } 
    dest.unlock(); 
} 
+0

Que sont c1 et c2 dans votre exemple d'actionscript? Couleur? – bkildow

+0

Oui, désolé j'ai déplacé ce code d'ailleurs et ai dû le modifier un peu. Cela devrait être réparé maintenant. – Adam

+0

Notez aussi qu'il y avait une paire de lignes manquantes après dest.setPixel – Adam

0

il semble que le code ci-dessus ferait une gamme de couleurs transparentes.

pseudo-code:
        pour chaque pixel dans targetBitmapData
                si la couleur de pixel est> = # FFF7F0F2
                        changer de couleur à # 00FFFFFF

quelque chose comme ça ne sera jamais parfait, car vous perdrez toutes les couleurs claires je trouverais un sélecteur de couleur en ligne que vous pouvez utiliser pour voir exactement quelles couleurs seront modifiées

1

vous pouvez réellement faire sans PixelBender et temps réel grâce à l'threshold function intégré:

// Creates a new transparent BitmapData (in case the source is opaque) 
var dest:BitmapData = new BitmapData(source.width,source.height,true,0x00000000); 

// Copies the source pixels onto it 
dest.draw(source); 

// Replaces all the pixels greater than 0xf1f1f1 by transparent pixels 
dest.threshold(source, source.rect, new Point(), ">", 0xfff1f1f1,0x00000000); 

// And here you go ... 
addChild(new Bitmap(dest));  
+0

Oups, vous devez avoir édité votre réponse pendant que j'écrivais ceci ... –

0

la réponse en 1 pixel de code bender:

dst = float4 ((distance (courant.rgb, couleur) < seuil)? 0,0: courant);

devrait être:

dst = (distance (current.rgb, couleur) seuil <)? float4 (0.0): courant;

ou

if (distance (current.rgb, couleur) seuil <) dst = float4 (0.0); sinon dst = float4 (courant);