[Java] JPG in Applikation einfügen

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von phL, 9. Januar 2013 .

  1. 9. Januar 2013
    JPG in Applikation einfügen

    Hey Leute,

    ich hab zwei Fragen an euch:

    1. Ich habe bereits ein Bild in meine Applikation an der richtigen Stelle eingefügt, nur lädt mein Spiel jetzt extrem langsam. Wie änder ich das dahingehend, dass es wieder flüssig läuft? Das Bild ist lediglich 120x60 groß und dürfte eigentlich ja kein großer Aufwand sein.

    Danke
     
  2. 9. Januar 2013
    AW: JPG in Applikation einfügen

    Poste halt mal den Code (Ausschnitt), sonst können wir dir nicht helfen.
     
    1 Person gefällt das.
  3. 10. Januar 2013
    AW: JPG in Applikation einfügen

    Das Bild ist eig. irrelevant, da es ziemlich klein ist.
    Dennoch die Frage. Cached du das Bild oder lädst du es, bei jedem "Update" des Games, neu?

    Liegt der Fehler vll. an deinem restlichen Code?
    Lief es vorher flüssig?
     
  4. 10. Januar 2013
    AW: JPG in Applikation einfügen

    Falls du eclipse als IDE nutzt:

    Eclipse Test & Performance Tools Platform Project

    Find ich super geil, siehst du jede Methode etc. wie viel Zeit diese braucht, wie oft eine Schleife durchgelaufen wird etc.

    Daran siehst du, wo genau es hängt.
     
  5. 13. Januar 2013
    AW: JPG in Applikation einfügen

    Ja mein Problem aktuell ist, dass ich das Bild bei jedem Update neu lade (bzw. bei jedem Updateschritt kommen erste eine Reihe von if-else-Abfragen, bis er in irgendeine von den 10 Abfragen reingeht und dieses dann zeichnet)

    Wie mache ich das mit dem Cache?

    Danke für eure Antworten!
     
  6. 13. Januar 2013
    AW: JPG in Applikation einfügen

    Ich weis nicht ob dies 100% richtig ist, aber ich würde es folgend machen.

    Neue Klasse erstellen.
    "Singleton" Konstruktor
    - prüfe ob statische Variable != Null
    - Wenn statische Variable == Null -> lade Bild in statische Variable
    - Wenn statische Variable != Null -> return statische Variable

    Somit sollte er das Bild nur einmal laden und ansonsten aus dem "Cache" nehmen.
     
    1 Person gefällt das.
  7. 13. Januar 2013
    AW: JPG in Applikation einfügen

    "gecached" sollte es doch sein, solange das ImageIcon Objekt lebt.

    Also nicht immer wieder ein neues Objekt erstellen sondern einmal erstellt und dieses Objekt verwenden.
     
  8. 13. Januar 2013
    AW: JPG in Applikation einfügen

    kann leider damit nicht besonders viel anfangen. was ich bisher gemacht habe:

    Hauptspiel:
    Code:
     private boolean updateWind;
     private updateWind windleiste;
     
     public BufferedImage loadUpdateWind() throws IOException{
     return windleiste.getwindBuffer();
     }
    ...
    
    public TankGame() {
     ...
     this.windleiste = new updateWind();
     this.updateWind = true;
     ...
    }
    
    public void paintGame(Graphics g) {
    if (updateWind == true) {
     try {
     windleiste.updateWindBuffer();
     } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     }
     updateWind = false;
     }
    }
    
    
    Und dann hab ich eine Klasse erstellt mit dem Namen updateWind:

    Code:
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    public class updateWind extends TankGame {
     private BufferedImage windBuffer;
     private BufferedImage image;
     
     public updateWind(){
     }
    
     
     public void updateWindBuffer() throws IOException {
     
     if (getWx() == -21) {
     image = ImageIO.read(new File("leisteblau3.jpg"));
     } else if (getWx() == -14) {
     image = ImageIO.read(new File("leisteblau2.jpg"));
     } else if (getWx() == -7) {
     image = ImageIO.read(new File("leisteblau1.jpg"));
     } else if (getWx() == 0) {
     image = ImageIO.read(new File("leisteleer.jpg"));
    
     } else if (getWx() == 7){
     image = ImageIO.read(new File("leisterot1.jpg"));
    
     } else if (getWx() == 14){
     image = ImageIO.read(new File("leisterot2.jpg"));
    
     } else if (getWx() == 21){
     image = ImageIO.read(new File("leisterot3.jpg"));
    
     } else {
     image = ImageIO.read(new File("test.jpg"));
     }
     
     windBuffer = image;
     Graphics2D test = windBuffer.createGraphics();
     paint(test);
     }
     
     public BufferedImage getwindBuffer() throws IOException {
     if (windBuffer != null) {
     return windBuffer;
     } else {
     updateWindBuffer();
     return windBuffer;
     }
     }
     
     public void paint(Graphics g){
     g.drawImage(image, 460, 550, this);
     }
    }
    
    mein Problem ist gerade, dass ich nicht weiß, was ich in den Konstruktor schreiben soll und er so, wie es gerade ist, ständig das Spielfeld neu öffnet ohne das was passiert.

    Was soll in den Konstruktor rein?

    Danke fürs durchlesen!
     
  9. 13. Januar 2013
    AW: JPG in Applikation einfügen

    Das Problem liegt in der Methode updateWindBuffer()

    Wenn diese Methode durchgeführt wird, gibts nen Dateisystemzugriff und das Bild wird ständig neu geladen.

    Erstelle einfach einmal Objekte zu den Bildern und dann werden diese nicht immer wieder neu geladen.
     
    1 Person gefällt das.
  10. 13. Januar 2013
    AW: JPG in Applikation einfügen

    ich habs jetz anders gelöst:

    Ich verändere einfach bei jedem Spielerwechsel das Bild in einer extra Methode (alles in meiner Spielklasse). Dieses wird in der paint-Methode die ganze Zeit gezeichnet; ganz verstehen, warum es jetzt keine Probleme macht, davor aber schon, tue ich zwar nicht, aber das ist erstmal auch ok so ist nur ne hausaufgabe und solange es stimmt, is alles ok

    danke euch für euer engagement, eine bewertung ist obligatorisch.
     
  11. 13. Januar 2013
    AW: JPG in Applikation einfügen

    Was auch immer du da jetzt gemacht hast (habe deinen Beitrag 10x gelesen und es nicht verstanden):

    Wenn es nicht dem Vorschlag von unix entspricht ist es schlecht. Du solltest jedes Bild nur einmal über ImageIO.read read laden und dann mit den geladenen Objekten arbeiten.
     
  12. 13. Januar 2013
    AW: JPG in Applikation einfügen

    ich lade es nur einmal denke ich, ich poste euch mal ein wenig Code, vielleicht könnt ihr ja was damit anfangen:

    Das ist meine Methode:
    Code:
    public void updateWindleiste() throws IOException {
    
     if (wx == -21) {
     image = ImageIO.read(new File("leisteblau3.jpg"));
     } else if (wx == -14) {
     image = ImageIO.read(new File("leisteblau2.jpg"));
     } else if (wx == -7) {
     image = ImageIO.read(new File("leisteblau1.jpg"));
     } else if (wx == 0) {
     image = ImageIO.read(new File("leisteleer.jpg"));
    
     } else if (wx == 7) {
     image = ImageIO.read(new File("leisterot1.jpg"));
    
     } else if (wx == 14) {
     image = ImageIO.read(new File("leisterot2.jpg"));
    
     } else if (wx == 21) {
     image = ImageIO.read(new File("leisterot3.jpg"));
    
     } else {
     image = ImageIO.read(new File("test.jpg"));
     }
     }
    
    In meiner paintGame Methode habe ich folgendes reingeschrieben:
    Code:
     g.drawImage(image, 460, 550, this);
    
    und bei jedem mal, wenn die Methode changePlayer() aufgerufen wird (also wenn eine Kugel in den Hintergrund oder Panzer einschlägt und genullt wird), dann

    Code:
    try {
     updateWindleiste();
     } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     }
    
    hoffe ich hab das jetzt richtig gemacht, funktionieren tut es jedenfalls

    //edit:
    natürlich habe ich zu beginn meiner klasse
    Code:
     private BufferedImage image;
    
    stehen
     
  13. 13. Januar 2013
    AW: JPG in Applikation einfügen

    Okay, da du es scheinbar noch nicht ganz verstanden hast hier ein Beispiel, wie du es in deinem Projekt machen könntest:

    Neue Methode + einer Map:
    Code:
    private Map<String, BufferedImage> cachedImages;
    
    private BufferedImage getImage(String imageFile) throws IOException {
     if (cachedImages == null)
     cachedImages = new HashMap<String, BufferedImage>();
    
     if (!cachedImages.containsKey(imageFile))
     cachedImages.put(imageFile, ImageIO.read(new File(imageFile)));
    
     return cachedImages.get(imageFile);
    }
    
    Deine Methode:
    Code:
     
    public void updateWindleiste() throws IOException {
     if (wx == -21) {
     image = getImage("leisteblau3.jpg");
     } else if (wx == -14) {
     image = getImage("leisteblau2.jpg");
     } else if (wx == -7) {
     image = getImage("leisteblau1.jpg");
     } else if (wx == 0) {
     image = getImage("leisteleer.jpg");
     } else if (wx == 7) {
     image = getImage("leisterot1.jpg");
     } else if (wx == 14) {
     image = getImage("leisterot2.jpg");
     } else if (wx == 21) {
     image = getImage("leisterot3.jpg");
     } else {
     image = getImage("test.jpg");
     }
    }
    (Ich würde das übrigens mittels Switch anstatt der vielen Abfragen lösen)

    Der Vorteil liegt darin, dass jedes Bild NUR EINMAL aus dem Dateisystem gelesen wird und dann in der Map zwischengespeichert ist. So vermeidest du unnötiges Lesen von der Festplatte und gewinnst an Geschwindigkeit.

    Du solltest die getImage Methode überall da verwenden, wo du irgendwelche Bilder lädst.
     
  14. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.