2013-02-13 9 views
5

Muszę mieć po prostu panel wewnątrz którego będę mógł rysować. Chcę móc rysować piksel po pikselu w postaci .Java: podstawowe kreślenie, rysowanie punktu/kropka/piksel

ps: Nie potrzebuję linii/okręgów innych prymitywów. pps: biblioteka graficzna naprawdę nie ma znaczenia, może to być awt, swing, qt .. nic. Chcę tylko mieć coś, co zwykle reprezentuje Bufferedimage lub coś takiego, w którym ustawiasz kolory pojedynczych pikseli, a następnie renderujesz je na ekranie.

+0

Niestety java nie ma żadnej metody do rysowania pojedynczego punktu, zamiast tego musisz użyć 'drawLine' z tym samym punktem zarówno dla początku i końca. –

+1

@ ExtremeCoders: to jest żałosne i czy to nie jest straszne obciążenie? Chcę tylko móc wyświetlać duże zbiory danych. –

Odpowiedz

2

reprezentowany przez BufferedImage ..

Proponuję BufferedImage za to wyświetlany ..

..or coś takiego, gdzie można ustawić kolory pojedynczych pikseli, a następnie uczynić go na ekranie.

..w JLabel - jak widać w this answer.

Oczywiście, gdy mamy instancję BufferedImage, możemy setRGB(..).

2

Jeśli naprawdę potrzebujesz renderować piksel po pikselach, zrobiłem to, by uzyskać wizualizację punktu dostępowego, które napisałem dla laboratorium badawczego.

To, czego potrzebujesz, to BufferedImage.setRGB(..) - jeśli rysujesz piksel po pikselu, zakładam, że zaimplementowałeś algorytm, który wyrenderuje wartości RGB dla każdego piksela (podobnie jak w przypadku map ciepła). Właśnie tego używaliśmy w starej apliakcji zgodnej z IE. Pracował jak urok i był stosunkowo szybki, biorąc pod uwagę to, co robił.

Niestety za każdym razem, gdy manipulujesz wartościami RGB bezpośrednio w obrazie buforowanym, zostanie on usunięty z pamięci przez pamięć wideo.

Od Javy 7 słyszałem, że podstawowa implementacja J2D podejmie próbę ponownego buforowania obrazu do pamięci wideo po zakończeniu operacji i ponownym renderowaniu - na przykład renderują mapę cieplną, która nie jest przyspieszana, ale po jej renderowaniu, podczas przeciągania okna i pracy z aplikacją, dane obrazu podkładu mogą zostać ponownie przyspieszone.

+0

dziękuję, próbuję zrobić coś podobnego - mam serię widm (mierzonych w sposób ciągły w czasie) i chcę je narysować jako mapę 2D, kolorowanki według intensywności. Więc będzie wyglądać jak mapa termiczna. Ale jest dużo danych do wykreślenia i mam nadzieję, że zaimplementuję pewne inteligentne buforowanie i gwintowanie danych, abyśmy mogli zwiększyć/zmniejszyć prędkość. –

+0

@chhh - bardzo mile widziane! Kiedy zaimplementowaliśmy zoom, trzymaliśmy się wokół ostatecznego obrazu BufferedImage przy każdym poziomie powiększenia (więc nie musieli być ponownie renderowani), ale jeśli rozdzielczość jest zbyt wysoka, powoduje to rozerwanie HEAP, dzięki czemu można je zapisać jako PNG, aby dysk i ładuj/ponownie renderuj je w locie lub w razie równej sztuczki, jeśli potrzebujesz. Dla nas przynajmniej było to jeszcze szybsze, niż ponowne przeliczenie ramki. –

2

Przykładem jeden sposób, aby to zrobić:

// 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 


a następnie od wewnątrz zastąpionej paintComponent (Graphics g)

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

Dzięki, spróbuję czegoś takiego. Czy masz coś na myśli, aby zaproponować mi dalszą lekturę tego rodzaju grafiki w Javie? –

+0

Możesz już o tym wiedzieć, ale na wszelki wypadek: [http://docs.oracle.com/javase/tutorial/2d/index.html](http://docs.oracle.com/javase/tutorial/2d/ index.html) – Jool

0

Jeśli chcesz szybko coś zrobić, można po prostu użyj metod Graphics setColor i drawLine. Na przykład:

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); 
} 

Użyłem tej techniki i nie było strasznie wolno. Nie porównałem go do obiektów BufferedImage.

0

Trochę późno tutaj, ale zawsze można zrobić to tak, programiści Java gry Czy, z Screen Klasa:

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 
      } 
    } 

} 

A potem w głównej klasie:

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(); 
} 

które powinny praca, myślę.