|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
[java] disegnare sopra Component (stream da webcam)
ciao ragazzi!
allora vi spiego il mio problema: io sto usando jmf per ricavare uno stream video da una webcam, per poterlo visualizzare il player che realizzo mi ritorna un Component e io semplicemente lo appiccico a un JFrame e vedo lo stream, il mio problema è che con questa webcam io devo realizzare un multitouch e quindi ho bisogno di calibrare dei valori appena parte il programma, questi li metto a posto facendo toccare all'utente il pannello (messo sopra la web) in diverse regioni. per fare una interfaccia userfrendly vorrei poter disegnare SOPRA lo stream così che l'utente possa vedere dove toccare. ora la mia domanda è come diavolo faccio? se io ho il Component c0 (che sarebbe lo stream) non posso farmi passare il sio graphics e disegnare con quello, perchè mi dà errore, quindi come potrei fare? grazie a quelli che ci hanno capito qualcosa ![]() ![]() ![]() ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se escludiamo il fatto che praticamente non mi ricordo più niente di specifico su JMF, la faccenda è semplicissima.
Prendi la webcam, apri il flusso video, lo disegni su un buffer (BufferedImage), copi quel buffer su un componente swing e ci disegni sopra o sotto, come preferisci. Oppure, ancora più semplice, usi un Panel con un layout di tipo OverlayLayout. OverlayLayout consente di sovrapporre dei componenti. Sotto ci metti il Component del Player collegato alla webcam, sopra un Component personalizzato che, sovrascrivendo il metodo paint (siamo in AWT), disegna quel che vuoi sopra al flusso video. Oppure puoi usare un FrameGrabber e un BufferToImage per ottenere degli "snapshot" della webcam da usare durante la calibrazione. Insomma, hai un tot di alternative. Io proverei prima quella dell'OverlayLayout. |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
Quote:
![]() PS: che cosa bisogna utilizzare per creare un menu carino con animazioni? (simile a quello di windows surface per intenderci ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Bisogna inannzitutto saper disegnare. E questo è in genere l'ostacolo più grosso perchè un conto è la cosa magari caruccia che sa disegnare un programmatore e un conto è quell'interfaccia strafichissima che è in grado di disegnarti un grafico.
La realizzazione tecnica è poi solitamente super banale. javax.swing.Timer per animare le immagini disegnate su un qualsiasi componente o per realizzare le trasformazioni (traslazioni o rotazioni) dei componenti disegnati su un contenitore e il gioco è bell'e che finito. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
mmm hai ragione sono i disegni che sono da sbav di solito
![]() magari trovo qualcosa di già fatto ![]() grazie mille per l'overlaylayout che funziona a meraviglia!!! ora lo implemento nel codice dello stream e ci lavoro un pò sopra ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
mmmm l'overlaylayout se ne sbatte quando c'è lo stream (infatti funziona con due miei component), sarà perchè si aggiorna in continuazione.. caspita era ottima l'idea, altri gestori di layout che permettono uno z index?
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
direi che il componente del player si fa beffe dell'ordine z.
Opzione B. FrameGrabber e BufferToImage, poi disegni l'immagine su un component (in questo caso puoi usare anche componenti Swing). |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
Quote:
quale sarebbe il componente più "base" e leggero di swing per far disegnare un'img? dovrebbe essere JComponent che estende direttamente gli awt container e component.. mi sbaglio? perchè a me non serve che mi metta a disposizione un sacco di cose, basta che abbia il metodo paint da sovrascrivere (per disegnare la mia griglia) e possa disegnare in'immagine, devo stare attento alle prestazioni purtroppo ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
puoi usare anche un component awt. Con l'uso di framegrabber comunque perdi qualcosa in prestazioni. Bisogna vedere se le performace risultanti restano nell'alveo delle aspettative.
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
ok ci provo vediamo cosa viene fuori
![]() ma visto che ne sai, c'è un tool o qualcosa che mi faccia da benchmark? uso eclipse come ide, e mi servirebbe un riscontro reale(non solo teorico) se un algoritmo è + o - veloce di un altro... ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Diciamo che l'impatto dovrebbe essere sufficientemente evidente da poter essere rilevato tramite un profiler (cioè noterai un incremento delle operazioni di gestione della memoria in termini di allocazione-deallocazioni della young generation e un uso più intenso del processore).
Un profiler tipo jvisualvm è in grado di dirti anche il tempo medio di esecuzione di un singolo metodo. Una comparazione tra il prima e il dopo dovrebbe quindi quantificare il peggioramento di performance. |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
ok grazie!!
lo proverò domani, intanto funziona il metodo di grabbare il frame e spararlo su un Component, operazione che tra l'altro dovevo fare comunque visto che li devo analizzare uno ad uno, quindi ne creo solo una copia e non perdo neanche molto in prestazioni ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
caspita non riesco a farlo funzionare con eclipse, va beh non importa..
senza aprire un altro 3d ti volevo chiedere gentilmente se mi potresti spiegare come funziona il doppio buffering? così non ho problemi di "refresh" ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Il principe del double buffering in Java è BufferStrategy.
Molto semplicemente si tratta di scavalcare in toto il meccanismo di rendering dei componenti AWT e andare a operare direttamente sui buffer hardware. Puoi specificare il numero di superfici da allocare (generalmente due) e lasciare che Java 2D si occupi di sostituire i buffer. Si prende un java.awt.Canvas (o un java.awt.Frame). Appena questo diventa visibile si crea un BufferStrategy invocando il suo metodo createBufferStrategy. A questo punto si avvia un ciclo di rendering la cui esecuzione è affidata all'Event Dispatcher (ad esempio tramite un javax.swing.Timer) e ciclicamente si recupera il BufferStrategy del canvas (getBufferStrategy), si disegna sul contesto grafico del buffer corrente (getDrawGraphics()) e si sostituiscono i buffer (bufferStrategy.show()). Un esempio potrebbe essere questo: Codice:
import java.awt.*; import java.awt.image.*; import javax.swing.*; import java.awt.event.*; public class Main { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { new Main().start(); } }); } private void start() { /* Esempio di operazione di disegno da passare a screen. */ final PaintCallback paint = new PaintCallback() { public void draw(Graphics2D g, int width, int height) { g.setPaint(Color.BLACK); g.fillRect(0, 0, width, height); g.setPaint(Color.WHITE); g.drawString("hello world", width / 3, height / 2); } }; final Frame window = new Frame("DoubleBuffer test"); final Screen screen = new Screen(paint); window.setLayout(new GridLayout(1, 1)); window.add(screen); window.addWindowListener(new WindowAdapter() { /** Avvia il ciclo di rendering di screen quando la finestra viene proiettata sullo schermo. */ public void windowOpened(WindowEvent e) { screen.start(); } /** Ferma il ciclo di rendering e chiude la finestra, terminando il programma se non ci sono altre finestre visibili o altri Thread non demoni in esecuzione. */ public void windowClosing(WindowEvent e) { screen.stop(); window.dispose(); } }); window.setSize(640, 480); window.setVisible(true); } } /** Dichiarazione di un'operazione di disegno su un contesto grafico. */ interface PaintCallback { public void draw(Graphics2D g, int screenWidth, int screenHeight); } /** Usiamo un Canvas per via del possesso da parte di questo componente di un BufferStrategy autonomo. */ class Screen extends Canvas { /* invocazione della funzione di rendering, impacchettata in un ActionListener per poterlo passare ad un javax.swing.Timer. */ private final ActionListener DO_RENDERING_CALL = new ActionListener() { public void actionPerformed(ActionEvent e) { doRendering(); } }; /* Pausa tra un'invocazione e la successiva di doRendering. Necessaria per evitare che l'Event Dispatcher Thread ritardi l'esecuzione delle operazioni di input */ private final int RENDERING_LOOP_DELAY_MS = 10; /* Un javax.swing.Timer esegue ciclicamente il metodo actionPerformed dell'actionListener nell'Event Dispatcher Thread */ private final javax.swing.Timer RENDERER = new javax.swing.Timer( RENDERING_LOOP_DELAY_MS, DO_RENDERING_CALL); /* numero di buffer da allocare per le operazioni di rendering. */ private final int BUFFER_COUNT = 2; /* operazione di disegno eseguita dal ciclo di rendering, definita esternamente a Screen (per comodità) */ private final PaintCallback PAINT_CALLBACK; /** Inizializza uno screen. Lo Screen esegue ciclicamente il metodo draw di paintCallback. PaintCallback non può essere null. */ public Screen(PaintCallback paintCallback) { if(paintCallback == null) { throw new IllegalArgumentException("paint callback cannot be null"); } PAINT_CALLBACK = paintCallback; } /** Questo metodo viene invocato dall'AWT quando questo componente diviene parte di un albero di componenti visibili. A partire da questo momento è possibile richiedere la creazione di un BufferStrategy. */ @Override public void addNotify() { super.addNotify(); createBufferStrategy(BUFFER_COUNT); } /** Avvia il ciclo di rendering. */ public void start() { RENDERER.start(); } /** Ferma il ciclo di rendering. */ public void stop() { RENDERER.stop(); } /** Esegue l'operazione di disegno definita in PAINT_CALLBACK usando il buffer corrente di BufferStrategy. */ private void doRendering() { BufferStrategy bs = getBufferStrategy(); if(bs != null) { do { do { int height = getHeight(); Graphics2D g = (Graphics2D)bs.getDrawGraphics(); PAINT_CALLBACK.draw(g, getWidth(), getHeight()); g.dispose(); } while(bs.contentsRestored()); bs.show(); } while(bs.contentsLost()); } } } |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
grazie sempre gentilissimo!
lo implementerò di sicuro tanto è semplice e utile ![]() ora devo creare gli eventi per il touch, sarà un bel casino.. anche perchè dovrò gestire tutto io.. già che sono qui ti chiedo un parere su come farlo, ecco la mia idea: semplificando io avrò un thred che costantemente monitora il touch e rileva i movimenti, quando i rilevamenti saranno compatibili con un evento (move click, etc) lancerò il metodo di un oggetto (che implementerà una mia interfaccia così non ho problemi con la firma dei metodi stessi e i paramentri), registrato precedentemente, corrispondente all'evento che ho rilevato. e a me basterà inserire il codice che voglio venga eseguito in corrispondenza di un move dentro la classe che implementa la mia interfaccia e che registrerò come handler di default. che ne pensi? ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Considerando che è possibile accodare eventi nella coda degli eventi di sistema e che questo accodamento genera una propagazione degli eventi a tutti i componenti awt/swing secondo il meccanismo predefinito io opterei per la creazione di un producer che converta i dati delle rilevazioni tramite webcam in eventi AWT.
Così facendo oltre a poter creare il tuo programma avresti la possibilità di usare un qualsiasi altro programma java dotato di interfaccia grafica già creato. Probabilmente c'è da riflettere sulla traduzione in eventi AWT di un interazione multipla con periferiche della stessa classe (il multitouch è come avere N mouse attivi ognuno dei quali genera eventi distinguibili). Penso che potrebbe essere gestito con un ID o meglio ancora delle sottoclassi di MouseEvent. Questo è più meno quello che mi viene in mente. |
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Sep 2007
Messaggi: 1071
|
Quote:
![]() ![]()
__________________
Affari: ariakasneverborne, PanCar, Luk@°°°, Fabio310, kintaro oe, krike, fabry180384, dariox am2, chiadoz, windsofchange, dado1979, Rudyduca, aleforumista, Sheva77 |
|
![]() |
![]() |
![]() |
#18 |
Junior Member
Iscritto dal: May 2009
Messaggi: 3
|
Salve ragazzi..ho letto quanto scritto e avrei un problema attinente alla discussione..
Sono riuscito a prende l'input da una webcam e attaccarlo su JPanel in java, fin qui nessun problema. Ora vorrei poter fare una sorta di touch come diceva andre, però non ho idea di come fare per prendere il movimento della mano. Ho visto su internet che molti giocano cn i colori e si fanno una sorta di track con la mano però non so come fare..Consigli? Grazie mille in anticipo.. ![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:28.