WPF: Come posso evitare lo strappo con WriteableBitmap?
Domanda
Sto usando un <= > per visualizzare le immagini che elaboro a circa 20 fotogrammi al secondo.
Questa domanda ( WPF: modo più efficiente di visualizzare rapidamente -cambiare le immagini? )
e questa domanda ( Come visualizzare immagini ad aggiornamento rapido senza grande allocazione di memoria? )
indica che il modo migliore per farlo è utilizzare WriteableBitmap
.
La documentazione per WritePixels()
indica che la chiamata Dispatcher.BeginInvoke()
sul thread dell'interfaccia utente farà sì che il thread di rendering ridisegni l'immagine:
Documentazione MSDN:
Il thread dell'interfaccia utente scrive il contenuto nel back buffer. Il thread di rendering legge il contenuto dal buffer anteriore e lo copia nella memoria video. Le modifiche al back buffer sono tracciate con regioni rettangolari modificate.
lt &; snip / >
Quando gli aggiornamenti vengono inviati al thread di rendering, il thread di rendering copia i rettangoli modificati dal buffer posteriore al buffer anteriore. Il sistema di rendering controlla questo scambio per evitare deadlock e ridisegnare artefatti, come & Quot; tearing & Quot ;.
Elaboro le mie immagini su un thread in background, quindi uso <=> per chiamare <=>, per assicurarmi che <=> sia chiamato sul thread dell'interfaccia utente.
Sto scoprendo che la lacerazione si verifica ancora con <=> e nell'applicazione su cui sto lavorando sembra orribile (è un'applicazione di imaging medico). C'è qualcosa che posso fare?
Soluzione
C'è stato molto lavoro in WriteableBitmap per evitare strappi, ma su alcune configurazioni di sistema questo è inevitabile. Ciò accadrà principalmente su Windows XP o Vista con Aero (DWM) disattivato.
Altri suggerimenti
Mentre chiami WritePixels () potresti sovrascrivere la tua bitmap. L'uso di Dispatcher.Invoke () anziché BeginInvoke () potrebbe essere d'aiuto.
So che questo è un vecchio thread, ma abbiamo avuto esattamente lo stesso problema e nel nostro caso è stato causato chiamando il nostro metodo di visualizzazione degli aggiornamenti utilizzando Dispatcher.BeginInvoke: il momento in cui siamo passati a Dispatcher. p>