Announcement

Collapse
No announcement yet.

Image und ColorModel

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Image und ColorModel

    Ich schreibe an Java-Applets für Fraktale (Apfelmännchen und Ähnliche). Erst hatte ich das Problem, daß sie sich nicht sauber schließen lassen, weil sie ständig zu 100% den PC auslasten, weil alles von paint() aus gesteuert wird (andernfalls kommen Bilder und Rechnugen durcheinander) und nie fertig wird. Da hatte ich die Bildausgabe pixelweise mit <br>

    g.setColor(new Color(coR[icf], coG[icf], coB[icf])); <br>
    g.drawLine(x,y,x,y);<br>

    wobei die Arrays coR[] usw. die 3 RGB-Farbanteile einer Farbtabelle sind, die vorher ausgerechnet bzw. in der Parameterliste ausgewählt wurde. Das icf ist sozusagen nur ein Grauwert (0..255), den das Iterationsprogramm als Ergebnis abgegeben hat. Das funktioniert bzgl. Farbe wie es soll.
    Die Bilder kamen relativ flott an, aber mit dem Nachteil, daß anschließend der Browser blockiert, man muß ihn erst vollkommen schließen, um ihn weiterzubenutzen. (Anzusehen unter http://www.webstickers.de, dort bei Fraktale am besten die Minis). <br>
    Es fehlten Threads. Das Übliche mit (Thread.sleep(10) dabei) usw. half nicht zuverlässig, weil immernoch zulange ohne Unterbrechung iteriert werden mußte. Die übrigen Programme (außer Fraktale) bei webstickers.de sind da schneller und so etwas sicher bzgl. Schließen. <br>

    Nun habe ich auf image-Bildausgabe umgestellt. Seitdem sind 2 Probleme offen: <br>
    a)Die Zeit hat sich vervierfacht, bis das nächste Bild kommt. <br>
    b)Es kommt immer nur die default-Farbtabelle, nicht meine.

    <b>Die Methode beginnt mit </b>

    Image calculate() { <br>

    Thread me = Thread.currentThread(); <br>
    int alpha = 255, argb; <br>
    Color colorfract; <br>

    BufferedImage img = new BufferedImage(ixe,ixe,BufferedImage.TYPE_INT_ARGB) ; <br>
    ColorModel colModel = img.getColorModel(); <br>
    WritableRaster raster = img.getRaster(); <br>
    Color color; <br>

    <b>und endet mit: </b>

    color = new Color(colR[icf], colG[icf], colB[icf]); <br>
    argb = color.getRGB(); <br>
    Object colData = colModel.getDataElements(argb,null); <br>

    raster.setDataElements(ix,iy,colData); <br>
    } // Ende for ix <br>
    }; // Ende for iy <br>

    if (runner != me) <br>
    return null; <br>

    return img; <br>

    } // Ende Image calculate <br>

    Das steht so ähnlich bei Core Java2 Bd.1 Seite 604. <br>
    Der Rest(Threads, run(), paint()) ist wie bei DitherTest.java aus den Demos vom jdk.

    Weiß jemand, wie ich die Default-Tabelle loskriege ? <br>
    Und: Warum ist das Programm jetzt so entsetzlich langsam ?

    Herzliche Grüße <br>
    Gabi

  • #2
    Um es mal so zu sagen du machst es dir so weit ich das sehen kann recht umständlich. Denn wenn du den Integer für RGB haben willst brauchst du doch erst gar nicht ein Color Objekt für <b>jeden einzelnen Pixel</b> erstellen. (<i>Objekte zu erstellen und sie wieder zu löschen kostetet im Verhältnis zu einfachen Feldern sehr viel mehr Aufwand</i>)Das ist ein mords aufwand. Hier gibt es einen einfacheren Weg.

    1. Wandle deine Farbe die in RGB vorliegt doch einfach selber in einen Integer um. Denn eine 32-bit Farbe unter Java besitzt folgendes Format: Argb - AARRGGBB

    Mit dieser Methode kannst du mit den bit-Operatoren diesen Integer leicht erstellen.

    public int getIntForColor(int r, int g, int b){<br>
    &nbsp;&nbsp;return (0xFF000000 | (r << 16) | (g << 8) | b);<br>
    }

    Dadurch solltest du schon mal einen Teil der Rechenleistung sparen.

    2. Ich habe mir außerdem mal die Applets angesehen und stellt fest das du immer gleich alles auf dem Bildschirm ausgibst. Es macht allerdings mehr Sinn die Veränderungen immer wieder in einem Bild des RAMs zu speichern. Dann kannst du die Veränderungen von einem Thread übernehmen lassen. Das BildUpdate (paint) sollte dabei nicht von dem Thread aus erfolgen welcher das Bild berechnet. Auerdem sollte sich der Thread, welcher das Bild berechnet hat, sich beenden indem du seine run() Methode einfach in leere laufen lässt.

    Um hier noch weitere Hilfe zu geben habe ich noch den Source für ein Applet online welches zwar keine Fraktale zeichnet, aber sich mit dem selben Problem herumschlägt.

    <a href="http://www.tobain.de.vu/java/applet/sources/">http://www.tobain.de.vu/java/applet/sources/</a>

    Ich hoffe das kann dir ein wenig weiter helfen.

    mfG Tobias Oelgart

    Comment

    Working...
    X