Java: Wie kann man die Pixel eines BufferedImage schnell kopieren? (Unit-Test enthalten)

Ich möchte eine Kopie (eines Rechteckbereichs) der ARGB-Werte aus einer Quelle erstellen.BufferedImage in ein ZielBufferedImage. Es darf kein Compositing durchgeführt werden: Wenn ich ein Pixel mit einem ARGB-Wert von 0x8000BE50 (Alpha-Wert bei 128) kopiere, muss das Zielpixel @ seigena 0x8000BE50, überschreibt das Zielpixel vollständig.

Ich habe eine sehr genaue Frage und habe einen Komponententest durchgeführt, um zu zeigen, was ich brauche. Der Komponententest ist voll funktionsfähig und in sich abgeschlossen. Er geht gut und macht genau das, was ich will.

Aber ich will einschneller und speichereffizienter Methode zum Ersetzen von copySrcIntoDstAt (...).

Das ist der springende Punkt meiner Frage: Ich bin nicht danach, wie man das Bild schneller "füllt" (was ich getan habe, ist nur ein Beispiel für einen Unit-Test). Ich möchte nur wissen, was ein @ wär schnell und speichereffizient Weg, um es zu tun (dh schnell und nicht unnötige Objekte zu erstellen).

Die von mir durchgeführte Proof-of-Concept-Implementierung ist offensichtlich sehr speichereffizient, aber langsagetRGB und einsetRGB für jedes Pixel).

Schematisch habe ich Folgendes: (wobei A die entsprechenden Pixel aus dem Zielbild vor dem Kopieren angibt)

AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA

Und ich möchte das haben:

AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAABBBBAAA
AAAAAAAAAAAAABBBBAAA
AAAAAAAAAAAAAAAAAAAA

wo 'B' steht für die Pixel aus dem src Bild

Bitte beachten Sie, dass ich nach einem genauen Ersatz für das @ suchcopySrcIntoDstAt (...) -Methode, nicht für einen API-Link / ein API-Zitat.

import org.junit.Test;

import java.awt.image.BufferedImage;

import static org.junit.Assert.*;

public class TestCopy {

    private static final int COL1 = 0x8000BE50;  // alpha at 128
    private static final int COL2 = 0x1732FE87;  // alpha at  23 

    @Test
    public void testPixelsCopy() {
        final BufferedImage src = new BufferedImage(  5,  5, BufferedImage.TYPE_INT_ARGB );
        final BufferedImage dst = new BufferedImage( 20, 20, BufferedImage.TYPE_INT_ARGB );
        convenienceFill( src, COL1 );
        convenienceFill( dst, COL2 );
        copySrcIntoDstAt( src, dst, 3, 4 );
        for (int x = 0; x < dst.getWidth(); x++) {
            for (int y = 0; y < dst.getHeight(); y++) {
                if ( x >= 3 && x <= 7 && y >= 4 && y <= 8 ) {
                    assertEquals( COL1, dst.getRGB(x,y) );
                } else {
                    assertEquals( COL2, dst.getRGB(x,y) );
                }
            }
        }
    }

    // clipping is unnecessary
    private static void copySrcIntoDstAt(
            final BufferedImage src,
            final BufferedImage dst,
            final int dx,
            final int dy
    ) {
        // TODO: replace this by a much more efficient method
        for (int x = 0; x < src.getWidth(); x++) {
            for (int y = 0; y < src.getHeight(); y++) {
                dst.setRGB( dx + x, dy + y, src.getRGB(x,y) );
            }
        }
    }

    // This method is just a convenience method, there's
    // no point in optimizing this method, this is not what
    // this question is about
    private static void convenienceFill(
            final BufferedImage bi,
            final int color
    ) {
        for (int x = 0; x < bi.getWidth(); x++) {
            for (int y = 0; y < bi.getHeight(); y++) {
                bi.setRGB( x, y, color );
            }
        }
    }

}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage