Image zeichnen effizienter machen...
-
Hi zusammen!
Ich habe eine Frage zur 2D-Technik von Java. Dazu erkläre ich am besten mal kurz an was ich programmiere:
Ich programmiere einen kleinen Bildbetrachter (Canvas), sozusagen nur als "Test", was man mit effizient Java machen kann (obwohl ich eigentlich ganz gut Java programmieren kann!). In dem Programm wird, logo, ein Bild geöffnet. In dieses Bild kann man reinzoomen und sich dann mittels "drag" (mouseDragged, gedrückte Maustaste) in dem Bild "bewegen".
Jetzt zu meinem Problem damit:
Wenn ich mir dabei die CPU-Auslastung ansehe, bin ich da locker bei 100% (1,6Ghz Rechner hab ich!). Das finde ich jetzt halt persönlich ein bisschen viel und würde das gerne effizienter machen, wenn möglich...!?!?
Eine Idee, die eigentlich nur was flickt, aber nicht so richtig besser macht, ist, daß ich zwischen jedem "Neuzeichnen" des Bildes ein Thread.sleep(xZeit) einfüge. Je nach Größe von xZeit kann ich damit schon die CPU-Last steuern, wobei dadurch alles natürlich ruckliger wird!Daher dachte ich, ihr habt vielleicht einen Tip für mich ,wie man so etwas einfach besser programmieren kann?
Ich mache das momentan im großen und ganzen mit einem Image-Objekt (mein Bild) und der MethodedrawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer)
D.h. ich kopiere immer den aktuell benötigten Ausschnitt aus dem Original-Bild auf den Bildschirm...
Würde mich sehr über Hilfe oder Tips freuen, da ich sowas ähnliches (dafür der Test!) auch in der Arbeit demnächst machen muss!
Vielen Dank schon mal und viele Grüße,
Tobias Schenk
-
Ich glaube die Vergrößerung komplett auf das Bild durchzuführen und die Ansicht über den sog. ViewPort einer ScrollPane zu steuern würde dein Problem entschärfen.
-
ok, danke!
und wie ist es mit DoubleBuffering? Kann das was bringen?
Gruß, Tobias
-
VolatileImage kann was bringen. Das benutzt nämlich im Gegensatz zu BufferedImage den Grafikkartenspeicher.
Probier mal das hier aus. Das Design ist allerdings noch verbesserungsfähig.
import javax.swing.*; import java.awt.event.*; import javax.imageio.*; import java.awt.image.*; import java.awt.*; import java.io.*; public class PictureDrag extends JFrame implements MouseListener, MouseMotionListener { BufferedImage image; VolatileImage vImg; int x_pos=0, y_pos=0, start_x=0, start_y=0; public static void main(String[] args) { PictureDrag frame = new PictureDrag(); } public PictureDrag() { setDefaultCloseOperation(EXIT_ON_CLOSE); getContentPane().addMouseMotionListener(this); getContentPane().addMouseListener(this); try { image=ImageIO.read(new File("test.png")); } catch (IOException e) { e.printStackTrace(); } setSize(640, 480); setVisible(true); vImg = getContentPane().createVolatileImage(image.getWidth(), image.getHeight()); Graphics g=vImg.createGraphics(); g.drawImage(image, 0, 0, null); } int mouse_start_x=0, mouse_start_y=0; public void mouseDragged(MouseEvent e) { start_x=x_pos; start_y=y_pos; x_pos=e.getX()-mouse_start_x-image.getWidth()/2; y_pos=e.getY()-mouse_start_y-image.getHeight()/2; paint(null); } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { mouse_start_x=e.getX(); mouse_start_y=e.getY(); } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void paint(Graphics g1) { Component c=getContentPane(); Graphics g=c.getGraphics(); int x, y, width, height; if(g1!=null) { x=c.getX(); y=c.getY(); width=c.getWidth(); height=c.getHeight(); g.setColor(Color.black); g.fillRect(x, y, width, height); } else { if(x_pos>start_x) { x=start_x; width=x_pos-start_x; } else { x=x_pos+image.getWidth(); width=start_x-x_pos; } g.setColor(Color.black); g.fillRect(x, start_y, width, image.getHeight()); if(y_pos>start_y) { y=start_y; height=y_pos-start_y; } else { y=y_pos+image.getHeight(); height=start_y-y_pos; } g.setColor(Color.black); g.fillRect(start_x, y, image.getWidth(), height); } if(vImg != null) { g.drawImage(vImg, x_pos, y_pos, null); } else if(image!=null) { g.drawImage(image, x_pos, y_pos, null); } } }
-
Hi, danke für en Tip!
Aber:
Es sollte auch mit Java 1.3 laufen, da sicher nicht jeder Windows-Anwender, der im Internet das Applet starten will, Lust hast 15mb runterzuladen...Hast du auch was Java 1.3-kompatibles?
Gruß, Tobias
-
tobis79211 schrieb:
Hi, danke für en Tip!
Aber:
Es sollte auch mit Java 1.3 laufen, da sicher nicht jeder Windows-Anwender, der im Internet das Applet starten will, Lust hast 15mb runterzuladen...Und wie kommst du auf die Idee, dass viele Leute Java 1.3 installiert haben?
Denn nur in dem Fall macht deine Argumentation Sinn.Versuch es doch einfach mit einem normalen BufferedImage.
Das könnte dann so aussehen:import javax.swing.*; import java.awt.event.*; import javax.imageio.*; import java.awt.image.*; import java.awt.*; import java.io.*; public class PictureDrag extends JFrame implements MouseListener, MouseMotionListener { BufferedImage image; Image vImg; int x_pos=0, y_pos=0, start_x=0, start_y=0; public static void main(String[] args) { PictureDrag frame = new PictureDrag(); } public PictureDrag() { setDefaultCloseOperation(EXIT_ON_CLOSE); getContentPane().addMouseMotionListener(this); getContentPane().addMouseListener(this); try { image=ImageIO.read(new File("test.png")); } catch (IOException e) { e.printStackTrace(); } setSize(640, 480); setVisible(true); vImg = getContentPane().createImage(image.getWidth(), image.getHeight()); Graphics g=vImg.getGraphics(); g.drawImage(image, 0, 0, null); } int mouse_start_x=0, mouse_start_y=0; public void mouseDragged(MouseEvent e) { start_x=x_pos; start_y=y_pos; x_pos=e.getX()-mouse_start_x-image.getWidth()/2; y_pos=e.getY()-mouse_start_y-image.getHeight()/2; paint(null); } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { mouse_start_x=e.getX(); mouse_start_y=e.getY(); } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void paint(Graphics g1) { Component c=getContentPane(); Graphics g=c.getGraphics(); int x, y, width, height; if(g1!=null) { x=c.getX(); y=c.getY(); width=c.getWidth(); height=c.getHeight(); g.setColor(Color.black); g.fillRect(x, y, width, height); } else { if(x_pos>start_x) { x=start_x; width=x_pos-start_x; } else { x=x_pos+image.getWidth(); width=start_x-x_pos; } g.setColor(Color.black); g.fillRect(x, start_y, width, image.getHeight()); if(y_pos>start_y) { y=start_y; height=y_pos-start_y; } else { y=y_pos+image.getHeight(); height=start_y-y_pos; } g.setColor(Color.black); g.fillRect(start_x, y, image.getWidth(), height); } if(vImg != null) { g.drawImage(vImg, x_pos, y_pos, null); } else if(image!=null) { g.drawImage(image, x_pos, y_pos, null); } } }
Teste das Programm mal. test.png kannst du auch durch ein anderes Bild ersetzen. Kann auch ein jpg Bild sein. Dann versuch mal das Bild mit der Maus zu verschieben.
-
ok, vielen Dank für den Tip!
Werde ich dieses WE (morgen) versuchen!die Sache mit Java 1.3 ist die:
Voraussichtlich haben viele von denen noch kein Java installiert und ich möchte einfach nicht, daß sich jeder User 15MB runterladen muss!
...Da werden viele einfach die Lust verlieren, glaub ich!
Gruß, Tobias
-
Ist das in Zeiten von Breitband noch so wichtig ob 8 oder 15 MB??
-
tobis79211 schrieb:
Voraussichtlich haben viele von denen noch kein Java installiert und ich möchte einfach nicht, daß sich jeder User 15MB runterladen muss!
Du bist also der Meinung, dass es noch zumutbar ist die 10MB für Java 1.3 runterzuladen aber 15MB für 1.4 ist zuviel?
Verstehe ich nicht.
-
ich bin der Meinung, daß 1.3 5,2MB hat, nicht 10...
Ergo: 5 oder 15!