Erkennen von transparenten und opaken Pixeln in ActionScript

Oft bekommt man als Entwickler ein .png, das als Button dienen soll. Hier ist wie immer der einfache Weg, Bild einbinden und den Container klickbar machen. Das ist ja soweit kein Hexenwerk. Jedoch kann das zu unschönen Effekten führen, da natürlich auch die transparenten Teile des Bildes Klickbar sind und somit Bereiche interaktiv, die rein optisch gesehen, nicht mehr zum im Bild enthaltenen Objekt gehören.

Klar kann man jedes mal eine Überprüfung des unter dem Mauszeiger liegenden Pixels machen und prüfen ob dieser nun transparent ist oder eben nicht. Aber es wäre doch schön, einfach eine Fläche zu haben, die man als ClickArea über das Bild legen kan, um darauf die MouseListener zu legen, ohne jedes Mal irgendwas abzuprüfen, was eventuell zu unschönen Seiteneffekten führt.

Die simple Variante hierfür ist eine BoundingBox zu generieren, welches das Rectangle repäsentiert, in dem die opaken Flächen liegen. Für hauptsächlich rechteckige Formen sollte das ausreichend sein. Aber was ist wenn, die Form komplexer ist oder einfach nicht Rechteckig? Das führt dann zu folgendem Ergebnis:

This movie requires Flash Player 9

Das ist bei dieser Form kein wirklich akzeptables Ergebnis. Man hätte sich hier auch einfach die Mühe sparen können. Also benötigt es einen anderen Ansatz, die eine Annäherung an die Form ermöglicht und so eine bessere BoundingBox zurückliefert.

Das Ansatz dazu klingt recht einfach. Man unterteilt das Bild in vier gleiche Rechtecke und schau nach, wie es mit den Transparenzen innerhalb der Fläche aussieht. Da gibt es drei Möglichkeiten: nur transparente, nur opake oder beides gemischte Pixel. Wenn es nur transparente Pixel sind, muss dieser Teil der Bildes nicht weiter untersucht werden. Genau das selbe gilt für die opaken Pixel. Jedoch sollte man sich hier den Bereich merken, da er ja zur BoundingBox des Bildes gehört, die ja Ziel der ganzen Aktion ist.

Bei den Rechtecken mit transparenten und opaken Pixeln muss man einfach wieder unterteilen und untersuchen. Dies sollte man aber nicht zu oft durchführen, da sich der Summe der Untersuchungen natürlich jedes mal vervierfacht. Im folgenden Beispiel habe ich 8 Iterationen verwendet, was zu einem recht guten Ergebnis führt:

This movie requires Flash Player 9

Die Überprüfung auf transparente und nicht transparente Pixel ist eigentlch recht einfach. Man nutzt das Rechteck aus der Unterteilung und führt die BitmapData.getPixels-Methode aus. Diese liefert einen ByteArray aller Farbwerte im Rechteck zurück und zwar 32-Bit. Über readUnsignedInt() bekommt man aus diesen wiederum die Farbwerte und kann diese über „>>> 24“ (Unsigned right shift) um eben 24 Bit nach rechts verschieben, womit der Alphakanal übrig bleibt. Hier bildet man die Quersumme der Alphawerte. Sollten diese 0x00 sein ist der Bildteil transparent, ist er 0xFF ist er eben opak. Hier lassen sich dann auch Toleranzen einfügen. Für die doch recht üppige Menge an Überprüfungen, ist es im übrigen besser eine Linked List zu nutzen, anstatt eines Arrays oder ArrayCollection.

Das ganze führt dann zu folgendem Ergebnis (grün sind die voll opaken Bereiche, die blauen die Randbereiche, die bei der letzten Iteration übrig bleiben):

This movie requires Flash Player 9

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.