2013-02-13 10 views
5

Ho bisogno di avere solo un pannello all'interno del quale sarei in grado di disegnare. Voglio potere disegnare pixel per pixel.Java: tracciamento di base, disegno di un punto/punto/pixel

ps: Non ho bisogno di linee/cerchi di altre primitive. pps: la libreria grafica non ha molta importanza, può essere awt, swing, qt .. qualsiasi cosa. Voglio solo avere qualcosa che di solito è rappresentato da Bufferedimage o qualcosa del genere in cui si impostano i colori dei singoli pixel e quindi si esegue il rendering sullo schermo.

+0

Sfortunatamente java non ha alcun metodo per disegnare un singolo punto, invece devi usare 'drawLine' con lo stesso punto sia per l'inizio che per la fine. –

+1

@ExtremeCoders: è un peccato, e questo non aggiunge un overhead orribile? Voglio solo essere in grado di visualizzare grandi set di dati .. –

risposta

2

rappresentato da BufferedImage ..

suggerisco una BufferedImage per questo, visualizzata ..

..o qualcosa del genere in cui si imposta i colori dei singoli pixel e poi renderlo sullo schermo.

.. in a JLabel - come visto in this answer.

Naturalmente, una volta che abbiamo un esempio di BufferedImage, possiamo setRGB(..).

2

Se si è onestamente necessario eseguire il rendering pixel per pixel, ho eseguito questa analisi per la parte di software di visualizzazione hotspot che ho scritto per un laboratorio di ricerca.

Quello che vuoi è BufferedImage.setRGB(..) - se stai disegnando pixel per pixel, presumo tu abbia implementato un algoritmo che renderà i valori RGB per ogni pixel (proprio come abbiamo fatto con le mappe di calore). Questo è ciò che abbiamo usato in una vecchia applet compatibile con IE nel corso della giornata. Ha funzionato come un fascino ed è stato relativamente veloce dato quello che stava facendo.

Sfortunatamente ogni volta che si manipolano i valori RGB direttamente in una BufferedImage, questa verrà annullata dalla memoria video di supporto.

Da Java 7, però, ho sentito che l'implementazione J2D sottostante farà un tentativo di ri-memorizzare l'immagine nella memoria video una volta che le manipolazioni si interrompono e il rendering viene ripetuto più e più volte - ad esempio, mentre tu stai rendendo la mappa di calore non è accelerato, ma una volta eseguito il rendering, mentre trascini la finestra e lavori con l'app, i dati dell'immagine di supporto possono essere riaccelerati.

+0

grazie, sto cercando di fare qualcosa di simile - ho una serie di spettri (misurati continuamente nel tempo) e voglio tracciarli come una mappa 2D, macchie coloranti secondo l'intensità. Quindi assomiglierà a una heatmap. Ma ci sono molti dati da tracciare, e spero di implementare un buffering intelligente e il caricamento dei dati con thread, in modo da poter ingrandire/ridurre ad una velocità decente. –

+0

@chhh - il benvenuto! Quando abbiamo implementato lo zoom, abbiamo mantenuto l'immagine del Buffered finale a ogni livello di zoom (quindi non è necessario ridisegnarlo) ma se la risoluzione è troppo alta, questo salta il tuo HEAP in modo da poterli scrivere come PNG per disco e caricare/ri-renderli al volo o qualche trucco uguale se necessario. Almeno per noi, è stato ancora più rapido farlo che ricalcolare e recuperare il frame. –

2

Un esempio di un modo per farlo:

// Create the new image needed 
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 

for (int rc = 0; rc < height; rc++) { 
    for (int cc = 0; cc < width; cc++) { 
    // Set the pixel colour of the image n.b. x = cc, y = rc 
    img.setRGB(cc, rc, Color.BLACK.getRGB()); 
    }//for cols 
}//for rows 


e poi da dentro paintComponent sovrascritto (Graphics g)

((Graphics2D)g).drawImage(img, <args>) 
+0

Grazie, proverò qualcosa del genere. Hai qualcosa in mente di suggerirmi per ulteriori letture su questo tipo di grafica in Java? –

+0

Forse lo sapete già, ma nel caso in cui: [http://docs.oracle.com/javase/tutorial/2d/index.html](http://docs.oracle.com/javase/tutorial/2d/ index.html) – Jool

0

Se si vuole fare qualcosa in fretta, si può solo usa i metodi Graphics setColor e drawLine. Per esempio:

public void paintComponent(Graphics g) { 
    super.paintComponent(g);  

    // Set the colour of pixel (x=1, y=2) to black 
    g.setColor(Color.BLACK); 
    g.drawLine(1, 2, 1, 2); 
} 

Ho usato questa tecnica e non era terribilmente lento. Non l'ho confrontato con gli oggetti BufferedImage.

0

Un po 'in ritardo qui, ma si può sempre farlo nel modo programmatori Java del gioco fanno, con una classe Screen:

public class Screen { 

    private int width, height; 

    public int[] pixels; 

    public Screen(int width, int height) { 
     this.width = width; 
     this.height = height; 

     pixels = new int[width * height]; 
    } 

    public void render() { 
     for(int y = 0; y < height; y++) { 
      for(int x = 0; x < width; x++) { 
       pixels[x + y * width] = 0xFFFFFF; //make every pixel white 
      } 
     } 
    } 

public void clear() { 
      for(int i = 0; i < pixels.length; i++) { 
        pixels[i] = 0; //make every pixel black 
      } 
    } 

} 

E poi nella classe principale:

private Screen screen; 

    private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
    private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); 

    public void render() { 
     BufferStrategy bs = getBufferStrategy(); 
     if (bs == null) { 
      createBufferStrategy(3); 
      return; 
     } 

     screen.clear(); 
     screen.render(); 

     for(int i = 0; i < pixels.length; i++) { 
      pixels[i] = screen.pixels[i]; 
     } 

     Graphics g = bs.getDrawGraphics(); 
     g.drawImage(image, 0, 0, getWidth(), getHeight(), null); 
     g.dispose(); 
     bs.show(); 
} 

Questo dovrebbe lavoro, penso.