Pixel setzen mit TYPE_INT_ARGB

Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hallo, nachdem ich es in einem anderen Thread versucht habe, dort aber keine Antwort bekam, roll ich mal das Thema neu auf:
Mein Programm soll einem BufferedImage, dass mit TYPE_INT_ARGB deklariert wurde, ein genau ausgewählten RGB mit Alpha-Wert ersetzen.
Leider habe ich schon viele Möglichkeiten aus dem Forum ausprobiert. Das Problem war meistens, dass dort statt TYPE_INT_ARGB -> TYPE_INT_RGB oder statt BufferedImage -> Image, etc. benutzt wurde.
Kann mir jmd. einen Lösungsvorschlag angeben?
 

muckelzwerg

Bekanntes Mitglied
Was genau willst Du denn wissen?
BufferdImage hat doch die "setRGB(...)" und "getRGB(...)" Methoden.
(ist zwar langsam, fuktioniert aber erstmal)

-- -- muckelzwerg
 
G

Gast

Gast
Mit denen funkioniert es. Aber wie du schon sagtest: sehr langsam :/
Ein Bild mit mindestens 1920 x 1024 Pxl. abzutasten und ggf. pixelweise zu ersetzen ist nicht die raffinierteste Methode. Gibt es nicht etwas schnelleres?
 

muckelzwerg

Bekanntes Mitglied
Du kannst die Daten direkt als array ansprechen.
Code:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

"Raffiniert" versteh ich nicht. Wenn Du jeden Pixel anschauen und evt. ändern musst, dann gehts halt nicht anders.
Du kannst ansonsten noch alle auf einmal zurückschreiben, mit
System.arraycopy(...), ob das in dem Fall Sinn macht ist ne andere Frage.

-- -- muckelzwerg
 
G

Gast

Gast
Und ".getData()" liefert den ARGB-Wert?
Das "raffiniert" nehme ich zurück ;) Wo du recht hast, hast du recht.
Aber gibt es nicht noch die Möglichkeit mit einer LookupTable?
 

muckelzwerg

Bekanntes Mitglied
Ich hab so ein bisschen das Gefühl, das Du weder in die Dokumentation schaust, noch die Hilfestellungen wirklich durcharbeitest.
setRGB() und getRGB() sind doch vollkommen eindeutig Kommentiert, was die Rückgabewerte angeht.
"getData()" ist eine Funktion der DataBuffer Klasse.
Schau in die Doku, wie sie funzt.
(kleiner Hinweis: Siehst Du in den zwei Zeilen irgendwo eine Indexangabe die den Pixel bestimmen könnte?)

-- -- muckelzwerg
 
G

Gast

Gast
Okay - ausholende Erklärung:
Ich lade ein Tileset als BufferedImage in das Programm rein. Dort wird es beim Laden sofort in skalierte Tile-Kompartimente zerlegt und - wie in der Tileset-Datei - angezeigt. (Nun sind die Tiles anklickbar und) man kann über ein kleines Preview-Fenster Pixel anklicken (deren RGB repräsentant für alle Pixel aus dem Tileset mit diesem speziellen RGB sind). Mittels Zuweisungsereignis werden im ganzen Tileset an den jeweiligen Stellen die Pixel mit Transparenz ersetzt. Mit anderen Worten: Das Durchlaufen aller Pixel ist gekoppelt an einer 4-fach verschachtelten for-Schleife. Das ist äußerst unschön ^^
 

muckelzwerg

Bekanntes Mitglied
Du holst den RGB-Wert des Pixels. "getRGB()".
Du holst alle Pixel "getData()".
Du läufst einmal linear über das Array und ersetzt jeden Pixel, falls er dem vorher ermittelten Wert entspricht.

-- -- muckelzwerg
 

Fancy

Aktives Mitglied
Moin,

Ergebnis einer kurzen persönlichen Fingerübung:

Code:
package fancy.jf.unsorted;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ColorAlternation {

    public static void main(String args[]) throws IOException, InterruptedException {

        // get some sample data
        final BufferedImage sample = ImageIO.read(ColorAlternation.class.getResource("/pic.png"));

        // setup our buffered work image
        final BufferedImage work = new BufferedImage(sample.getWidth(), sample.getHeight(), BufferedImage.TYPE_INT_ARGB);
        final Graphics2D g = work.createGraphics();
        g.drawImage(sample, 0, 0, null);
        g.dispose();

        // setup color src and dst
        final Color srcColor = new Color(0, 0, 0, 0);
        final Color dstColor = new Color(255, 255, 0, 255);

        final int src = (srcColor.getAlpha() << 24) | (srcColor.getRed() << 16) | (srcColor.getGreen() << 8) | (srcColor.getBlue() << 0);
        final int dst = (dstColor.getAlpha() << 24) | (dstColor.getRed() << 16) | (dstColor.getGreen() << 8) | (dstColor.getBlue() << 0);

        // setup threads
        final int maxThreads = 4;
        final Thread[] threads = new Thread[maxThreads];
        final long timeThreads = System.currentTimeMillis();

        // several times because it is so fast
        for (int j = 0; j < 1000; j++) {

            final int[] pixels = ((DataBufferInt) work.getRaster().getDataBuffer()).getData();

            for (int i = 0; i < maxThreads; i++) {
                final int thread = i;
                threads[i] = new Thread(new Runnable() {
                    public void run() {
                        for (int i = thread; i < pixels.length; i += maxThreads) {

                            // replace pixel
                            if (pixels[i] == src) pixels[i] = dst;
                        }
                    }
                });

                threads[i].start();
            }

            // wait for all threads
            for (int i = 0; i < maxThreads; i++) {
                threads[i].join();
            }

        }

        System.out.println((System.currentTimeMillis() - timeThreads) / 1000.0);

        // show image
        final JFrame frame = new JFrame();
        final JLabel label = new JLabel(new ImageIcon(work));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(label);
        frame.pack();
        frame.setVisible(true);
    }

}


Braucht für die vom Gast angegebenen Bildgrößen gerade mal 2.5 Millisekunden. Für 100MPixel immerhin 130 Millisekunden.

(Schade, hätte eigentlich gehofft es wäre langsamer, dann wäre noch Raum für Optimierungen gewesen. Lohnt sich aber bei den Zeiten wohl kaum, es sei den unser Gast arbeitet im > 100MPixel Bereich.)

Gruß,
Michael
 
G

Gast

Gast
@Fancy: Derartiges habe ich gesucht und werde es morgen gleich mal ausprobieren. Die Routine für den >100MPixel-Bereich würde ich dennoch optional mit einbauen wollen... *g* Allerdings kann ich mir nicht vorstellen, was man da noch alles optimieren kann o_O
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
BraunBerry Java Game Pixel "einfärben" Spiele- und Multimedia-Programmierung 6
T Probleme bei "Pixel-Fighting"-Spiel: Unausgewogene Mannschaften??? Spiele- und Multimedia-Programmierung 4
Q Mehr objekte darstellen als Pixel vorhanden Spiele- und Multimedia-Programmierung 6
Androbin Pixel-genaue Kollisionserkennung Spiele- und Multimedia-Programmierung 5
J Bestimmte Pixel transparent erscheinen lassen Spiele- und Multimedia-Programmierung 5
M pixel auslesen in JOGLE Spiele- und Multimedia-Programmierung 3
B Java Pixel Malen Spiele- und Multimedia-Programmierung 3
M Pixel eines BufferedImage bearbeiten (Performance) Spiele- und Multimedia-Programmierung 23
Kr0e OpenGL .. Pixel Buffer Objekt oder Frame Buffer Object? Spiele- und Multimedia-Programmierung 2
Steev LWJGL: org.lwjgl.LWJGLException: Pixel format not accelerated Spiele- und Multimedia-Programmierung 9
M pixel perfect collision detection bei rotierenden Bildern Spiele- und Multimedia-Programmierung 13
D cm in pixel Spiele- und Multimedia-Programmierung 37
R int[] der Pixel aus PNG oder JPG ? Spiele- und Multimedia-Programmierung 2
P Bild, Pixel- / Bereichsfarbe auslesen Spiele- und Multimedia-Programmierung 12
G Pixel Häufigkeiten entsprechent einfärben Spiele- und Multimedia-Programmierung 6
K Einzelne Pixel in einem Bild lesen Spiele- und Multimedia-Programmierung 5
S BMP-Bild Pixel für Pixel bearbeiten Spiele- und Multimedia-Programmierung 1
V Tranzparente Pixel Spiele- und Multimedia-Programmierung 5
S Pixel zeichnen Spiele- und Multimedia-Programmierung 3
G 2 dim. Pixel Array in AWT? Spiele- und Multimedia-Programmierung 7
I Java Andere Fenster in Borderless-Mode setzen Spiele- und Multimedia-Programmierung 16
S Mehrere Steine gleichzeitig setzen und bewegen Spiele- und Multimedia-Programmierung 4
0x7F800000 Stroke breite absolut in px setzen? Spiele- und Multimedia-Programmierung 19
B Position der ViewingPlatform und Visueller Objekte setzen Spiele- und Multimedia-Programmierung 3
T Wie kann ich ein OrbitBehavior auf einen festen Wert setzen? Spiele- und Multimedia-Programmierung 2
A QuadArray color setzen Spiele- und Multimedia-Programmierung 10
S Koordinaten bestimmen und setzen Spiele- und Multimedia-Programmierung 2
F Hintergrundfarbe setzen mit setBackground() Spiele- und Multimedia-Programmierung 7
D Focus richtig setzen? Aber wie ? Spiele- und Multimedia-Programmierung 2
A while Schleife - illegal start of type. Spiele- und Multimedia-Programmierung 4

Ähnliche Java Themen

Neue Themen


Oben