2009-03-18 14 views
15

Sto avendo uno strano problema, fondamentalmente in Java Graphics.drawImage() è estremamente lento su alcuni computer e più veloce su altri. Anche questo non è collegato alla potenza del computer, alcuni computer più deboli funzionano bene mentre alcuni più forti sembrano bloccarsi alla chiamata drawImage.Graphics.drawImage() in Java è ESTREMAMENTE lento su alcuni computer e molto più veloce su altri

Può essere o non essere correlato alla larghezza e all'altezza, ho una larghezza, un'ampiezza e una altezza molto grandi definite (qualcosa come 5000 per 2500). Non penserei che sia il problema tranne che come ho detto che corre in tempo reale su alcuni computer e più lentamente su altri e non sembra essere legato al potere relativo del computer.

Entrambi i computer hanno la stessa versione di Java, entrambi utilizzano Vista. Uno ha un Core 2 Duo da 1.83 ghz con 1gb di RAM e grafica integrata (funziona bene), l'altro ha un core 2 core ghz 2,53 con un 9600GS (ultimi driver nVidia) e 4GB di RAM e si blocca letteralmente sulla chiamata drawImage.

Qualche idea?

edit: ok questo è davvero strano, sto disegnando l'immagine in una finestra in Swing, ora quando ridimensiono la finestra e la ridimensiono l'immagine viene ridimensionata e diventa piccola. All'improvviso tutto procede senza intoppi, quando lo ridimensiono alla dimensione che era prima ancora che funzioni senza intoppi!

Ha anche più problemi di monitoraggio, se eseguo il trucco di ridimensionamento per farlo funzionare più velocemente su un monitor, quindi lo scorri su un altro monitor quando più della metà della finestra si trova nel nuovo monitor che ricomincia a scoppiare. Devo ridimensionare nuovamente la finestra per ridimensionarla e tornare alla sua dimensione originale per tornare indietro.

Se faccio il trucco di ridimensionamento su un monitor, spostarlo verso l'altro è di chugs naturalmente, ma se torno indietro al monitor originale su cui ho fatto il trucco di ridimensionamento funziona al 100%

Se ho due finestre mobili aperte (che visualizzano la stessa immagine), entrambe funzionano lentamente, ma se faccio il trucco di ridimensionamento su una finestra entrambe iniziano a girare senza problemi (tuttavia non è sempre così).

* quando dico ridimensionare la finestra, voglio dire renderlo il più piccolo possibile fino al punto in cui l'immagine non può essere effettivamente vista.

Potrebbe essere un errore Java?

+0

Che tipo di immagine è, e ciò che le versioni del JDK sono sui computer? –

+0

Penso di vedere lo stesso problema.Questo è JDK 8 su XP (sì lo so) e un display Hi-Color. Bastano un paio di secondi per eseguire il rendering di un'Immagine Bufferata contenente una schermata intera, ma solo la seconda (!) Volta in cui il componente viene disegnato. Le chiamate successive a drawImage sono di nuovo istantanee. Forse qualche conversione avviene internamente? Abbastanza confondendo tutto sommato, e non proprio accettabile che una semplice conversione del colore impieghi tanto tempo (se è la ragione). –

risposta

2

Ci sono diverse cose che potrebbero influenzare le prestazioni qui:

  • RAM disponibile
  • velocità della CPU
  • Scheda grafica (a bordo o separata)
  • driver grafico versione
  • Java
  • Modalità video utilizzata (risoluzione, bitdepth, supporto accelerazione)

MODIFICA: Dando un'occhiata alla domanda modificata, proporrei di verificare se il sistema 9600GS ha installato i driver NVIDIA più recenti. Di recente ho installato un driver per una scheda grafica Intel integrata che ha sostituito il driver generico di Windows e ha reso molto più veloce lo spostamento di finestre, la visualizzazione di video, la navigazione, ecc.

Tutte le altre specifiche sembrano buone. Forse Java non rileva il 9600GS e non usa l'accelerazione hardware, ma ne dubito.

Controllare anche la configurazione del sistema operativo. Su Windows, è possibile disattivare l'accelerazione hardware per scopi di debug.

Naturalmente il modo migliore per gestirlo sarebbe cambiare il codice: ridimensionare l'immagine o dividerla in blocchi come proposto dal DNS. Non sarai mai in grado di vedere l'intera immagine così com'è sullo schermo.

+0

Un computer è vecchio, stiamo parlando davvero vecchio e l'altro è nuovo e di fascia alta, ha CPU, RAM, grafica migliori ma la stessa versione di Java. Inoltre avrei potuto sbagliare con il 50.000x25.000, in realtà è 5000x2500. –

2

Come giudica il potere dei computer? Un'immagine 50x25 K a 32 bit richiede più di 4,5 GB di RAM da conservare in memoria (50000 * 25000 * 4 byte). Se un computer ha più RAM di un altro, ciò può fare un'enorme differenza di velocità, perché non dovrà passare al disco più spesso. Dovresti prendere in considerazione le sottosezioni dell'immagine e lavorare con quelle, invece dell'intera cosa.

Modifica: stai utilizzando i driver di grafica Java & più recenti? Se la tua immagine è solo 5Kx2.5K, l'unica cosa che posso pensare è che lo sta facendo senza alcuna accelerazione hardware.

+0

no Intendevo 5000x2000, ho trovato il numero di 50000x20000 piuttosto grande, poi ho realizzato che stavo mettendo uno 0 in più alla fine dei numeri, potrei andare lentamente alla cieca o qualcosa del genere. –

1

Controllare le impostazioni dello schermo. La mia scommessa è che la profondità dei pixel è diversa sui due sistemi e che quella lenta ha una profondità di pixel dispari in relazione all'oggetto dell'immagine che si sta tentando di visualizzare.

0

Poiché Java uses OpenGL to do 2D drawing, le prestazioni della tua app saranno influenzate dalle prestazioni OpenGL del chip grafico nel rispettivo computer. Il supporto per OpenGL sta diminuendo nel settore 3D, il che significa che (ironicamente) i chip più recenti potrebbero essere più lenti nel rendering di OpenGL rispetto a quelli più vecchi, non solo a causa dell'hardware, ma anche dei driver.

4

Se si utilizza Java di Sun provare alcuni dei seguenti proprietà di sistema, sia come parametri della riga di comando o le prime righe principali

 
sun.java2d.opengl=true //force ogl 
sun.java2d.ddscale=true //only when using direct3d 
sun.java2d.translaccel=true //only when using direct3d 

più bandiere possono essere visualizzati in this page

Guarda sun.java2d.trace che può consentire di determinare l'origine di prestazioni grafiche meno che desiderabili.

22

Le prestazioni di scrittura di un'immagine su uno schermo sono molto influenzate dal formato in cui è memorizzata l'immagine. Se il formato è uguale a quello richiesto dalla memoria dello schermo, può essere molto veloce; se non lo è, allora dev'essere fatta una conversione, a volte pixel per pixel, che è molto lenta.

Se si dispone di un controllo su come l'immagine è memorizzata, è necessario memorizzarla in un formato che lo schermo sta cercando. Ecco alcuni esempi di codice:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice device = env.getDefaultScreenDevice(); 
    GraphicsConfiguration config = device.getDefaultConfiguration(); 
    BufferedImage buffy = config.createCompatibleImage(width, height, Transparency.TRANSLUCENT); 
    Graphics g = buffy.getGraphics(); 

Se avete intenzione di disegnare l'immagine molte volte può valere la pena la conversione in un formato compatibile, anche se si è trattato in un altro formato.

Anche disegnare un'immagine sarà più lenta se la trasformi mentre disegni, che la parte "ridimensionante" della tua descrizione mi fa pensare che potresti essere. Ancora una volta, ridimensionare una volta (quando la finestra viene ridimensionata) e memorizzare nella cache l'immagine ridimensionata e compatibile in modo che possa essere ridisegnata rapidamente.

+3

questo ha funzionato perfettamente per me, grazie! Ho usato questo codice insieme a getRGB/setRGB per convertire il mio BufferedImage – Sam

+1

Big thanks! Ottima risposta, mi ha aiutato molto. Considera accettarlo. –

+0

Grazie mille per questo! Sono andato da ~ 17fps a 40 –

Problemi correlati