Undoable BufferedImage?

SuperFamicom

Aktives Mitglied
Hallo,

Ich suche eine Moeglichkeit, Aenderungen in BufferedImages undoable oder redoable zu machen. Aenderung heisst, es wird auf Knopfdruck ein bestimmter RGB-Wert im gesamten BufferedImage veraendert. Dies betrifft mehrere Pixel auf einen Schlag. Gleiches soll auch bei der Undo-Aktion wieder rueckgaengig machbar sein.

Weiss jmd. Rat?

(Sorry fuer englische Tastatur.)
 

Lars789852

Aktives Mitglied
Ich würd da erstmal als Anfang so rangehen, dass du die BufferedImages mit den einzelnen Schritten in einer ArrayList<BufferedImage> speicherst. Dann kannst du immer bei einem neuen Schritt das aktuelle hinzufügen. (Achtung, ich glaube, man muss das Bild clonen, sonst wird nur die Referenz gespeichert und alles ist umsonst). Wenn du dann etwas rückgängig machen willst, kannst du einfach in der Liste zurückgehen und das Bild als aktiv setzen, bei "redo" dann wieder ans Ende. Dann musst du noch implementieren, dass man nach einem oder mehreren "undo"s und einer Veränderung des Bildes die restlichen Bilder gelöscht werden, denn die sind ja nicht mehr gültig.

Das ganze kann man natürlich noch optimieren, um es performanter zu machen. Du könntest dann z.B. nur den Teil speichern, der verändert wurde, dazu solltest du eine Unterklasse von BufferedImage machen, die dann speichert, wo die Änderung war, vielleicht noch ein String für den User, was genau gemacht wurde, usw.
 

SuperFamicom

Aktives Mitglied
Hallo Lars789852, vielen Dank erstmal soweit. Ich habe das Problem mittlerweile anderweiteig versucht zu loesen (vlt. letzten Endes komplizierter als von dir vorgeschlagen), stosse aber nun auf Probleme mit der Redo-Funktion. Undo funktioniert so weit, nur Redo nicht.

Zunaechst habe ich ein Interface Undoable erstellt:
Code:
public interface Undoable {
    public void undo();    
    public void redo();
}

Dieses implementiere ich in der Klasse UndoableBufferedImage:
Code:
public class UndoableBufferedImage implements Undoable {
    
    private ImagePanel owner = null;
    protected BufferedImage img;
    
    public UndoableBufferedImage(BufferedImage img, ImagePanel owner) {
        super();
        this.img = img;        
        this.owner = owner;
    }

    @Override
    public void undo() {
        owner.setImage(img);
    }

    @Override
    public void redo() {        
        owner.setImage(img);
    }
    
}

Darueber hinaus gibt es noch den UndoManager:
Code:
public class UndoManager {
    private Node currentIndex = null;
    private Node parentNode = new Node();
    
    public UndoManager() {
        currentIndex = parentNode;
    }
    
    public UndoManager(UndoManager manager) {
        this();
        currentIndex = manager.currentIndex;
    }
    
    public void clear() {
        currentIndex = parentNode;
    }
    
    public void addUndoable(Undoable undoable) {
        Node node = new Node(undoable);
        currentIndex.right = node;
        node.left = currentIndex;
        currentIndex = node;
    }
    
    public boolean canUndo() {
        return currentIndex != parentNode;
    }
    
    public boolean canRedo() {
        return currentIndex.right != null;
    }
    
    public void undo() {
        if (canUndo()) {
            currentIndex.undoable.undo();
            moveLeft();
        }
    }
    
    public void redo() {
        if (canRedo()) {
            moveRight();
            currentIndex.undoable.redo();
        }
    }
    
    private void moveLeft() {
        if (currentIndex.left != null) {
            currentIndex = currentIndex.left;
        }
        
    }
    
    private void moveRight() {
        if (currentIndex.right != null) {
            currentIndex = currentIndex.right;
        }
        
    }
    
    private class Node {
        private Node left = null;
        private Node right = null;
        private final Undoable undoable;
        
        public Node(Undoable u) {
            undoable = u;
        }
        
        public Node() {
            undoable = null;
        }
    }
                
}

Der RGB wird ausgetauscht mit:
Code:
public void replaceRGB() {        
        if (img != null) {
            undoManager.addUndoable(new UndoableBufferedImage(img, this));
            img = convertRGB(img, srcColor, destColor);
        }
    }

Die jeweiligen ActionEvents der Undo- und Redo-Buttons loesen
Code:
undoManager.undo();
bzw.
Code:
undoManager.redo();
aus.

Sieht jemand, was hier falsch laeuft?

Andernfalls versuche ich es ueber die ArrayList<BufferedImage> und lass die Liste mit einem Index à la "currentIndex" durchlaufen, welcher beim Ausloesen der ActionEvents ueber die Undo/Redo-Buttons in-/dekrementiert.
Letztere waere erstmal eine Notfallloesung. Da ich spaeter die Undo/Redo-Funktionalitaet auf weitere undoable Objekte erweitern moechte, waere es ganz sinnvoll, saemtliche Objekte ueber undoable Interfaces und undoable Manager verwalten zu lassen (inklusive funktionierender Redo-Funktionalitaet).
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
D BufferedImage resize Allgemeine Java-Themen 16
RalleYTN JOGL Texture in BufferedImage konvertieren Allgemeine Java-Themen 1
M Input/Output BufferedImage vertauscht width und height Allgemeine Java-Themen 6
G BufferedImage und ByteArray Allgemeine Java-Themen 2
P Threads BufferedImage, Thread Concurrency Allgemeine Java-Themen 1
M Problem mit BufferedImage und PrinterJob im Querformat Allgemeine Java-Themen 1
T BufferedImage verändert sich beim Einlsesen Allgemeine Java-Themen 1
M BufferedImage toString() überschreiben Allgemeine Java-Themen 5
Thallius PDF von einem BufferedImage erstellen Allgemeine Java-Themen 1
S BufferedImage vergleich mit Subimage Allgemeine Java-Themen 1
reibi OutOfMemoryError bei Behandlung von BufferedImage's Allgemeine Java-Themen 6
TheSorm BufferedImage spiegeln Allgemeine Java-Themen 3
A BufferedImage einzelne Pixel transparent machen V2.0 Allgemeine Java-Themen 2
lumo 2D-Grafik BufferedImage und operationen darauf Allgemeine Java-Themen 2
K Image zu BufferedImage konvertieren Allgemeine Java-Themen 9
H BufferedImage Invertieren Allgemeine Java-Themen 13
D md5 berechnen für BufferedImage Allgemeine Java-Themen 5
D BufferedImage rotieren Allgemeine Java-Themen 8
TiME-SPLiNTER Binary BufferedImage automatisch croppen Allgemeine Java-Themen 4
F byte[] aus einem BufferedImage Allgemeine Java-Themen 3
0 BufferedImage - Farbton verändern Allgemeine Java-Themen 5
J BufferedImage aus PNG Files haben keinen Type Allgemeine Java-Themen 4
T umwandeln BufferedImage to File Allgemeine Java-Themen 7
reibi BufferedImage nach InputStream Allgemeine Java-Themen 10
Q BufferedImage enzelne Pixel tranzparent machen Allgemeine Java-Themen 2
S BufferedImage mit Transparenten Hintergrund Allgemeine Java-Themen 4
Z Farbe des Pixels rechts unten in einem BufferedImage? Allgemeine Java-Themen 4
R problem! bufferedimage speichern. Allgemeine Java-Themen 7
S BufferedImage als *.tga speichern Allgemeine Java-Themen 3
H Pixel im BufferedImage Manipulieren ? Allgemeine Java-Themen 17
Steev BufferedImage und setRGB() Allgemeine Java-Themen 10
P miese performance bei nem BufferedImage + repaint :( Allgemeine Java-Themen 6
M Drucken mit BufferedImage Allgemeine Java-Themen 9
M Problem mit Durchsuchen von BufferedImage Allgemeine Java-Themen 10
I BufferedImage etc Allgemeine Java-Themen 6
F BufferedImage -> Image Allgemeine Java-Themen 4
G BufferedImage benutzen Allgemeine Java-Themen 6
U BufferedImage.getSubimage ? paintComponent ? Allgemeine Java-Themen 4
T Bilder schnell in BufferedImage laden Allgemeine Java-Themen 4
G BufferedImage zeichnen Allgemeine Java-Themen 4
T BufferedImage aus einem byte-Array? Allgemeine Java-Themen 2
T BufferedImage problem Allgemeine Java-Themen 6
K 32-Bit grayscale BufferedImage Allgemeine Java-Themen 2
T Geschwindigkeit bei Polygonen und BufferedImage Allgemeine Java-Themen 9

Ähnliche Java Themen

Neue Themen


Oben