2012-01-22 12 views
9

Sto scrivendo un visualizzatore di immagini WPF, visualizzando una griglia di immagini. Sono sconcertato a causa delle prestazioni lente: la visualizzazione anche di una griglia 11 x 11 rende una VM poco reattiva, lenta e fiacca per lunghi periodi di tempo. Anche sul potente host le prestazioni in non-snappy.Come posso rendere più "scattante" la visualizzazione delle immagini su WPF?

Il programma si basa sul progetto in SO WPF: arranging collection items in a grid: Un oggetto ItemsControl è associato a Items, ObservableCollection. Ogni oggetto contiene un URI assoluto di file system. DataTemplate di ItemsControl contiene un elemento Image la cui origine è associata all'URI.

Sembra che il problema non possa essere il disco (SSD), la memoria (8 GB VM, 24 GB host) o CPU (i750). Inoltre, la maggior parte del lavoro è fatto da WPF, quindi non è nemmeno come se potessi individuare un problema nel mio codice: il mio codice carica semplicemente gli URI (cioè i percorsi delle immagini, non le immagini) per la raccolta e restituisce rapidamente. Poi c'è un'attesa e WPF mostra le immagini.

L'unico problema a cui potrei pensare è l'elaborazione delle immagini - riduzione graduale di WPF. Ma anche sull'host, che dispone di una scheda ATI Radeon HD "abbastanza buona" 5850, le prestazioni non sono ottimali.

Quindi, la mia domanda è: Come posso rendere più "scattante" la visualizzazione delle immagini su WPF?

Modifica: Le immagini sono JPEG HD a 22 bit a 1920x1080 acquisite da video HD m2ts. Ho provato a ridimensionarli (usando FFmpeg) in 'ega' 640x350. Lì era un miglioramento delle prestazioni ma le immagini ridotte di FFmpeg sembrano molto peggio di quelle di WPF.

Modifica: Grazie a David Osborne il codice ora funziona come x64. Ancora lento.

Modifica Ciò che ha migliorato la situazione è ciò che Matěj Zábský ha chiamato facendo scattare le immagini: riducendo la risoluzione. A beneficio dei futuri lettori:

  fullPath = new Uri(path, UriKind.Absolute); 


      BitmapImage smallerBitmapImage = new BitmapImage(); 
      smallerBitmapImage.BeginInit(); 
      smallerBitmapImage.DecodePixelWidth = (int) (theWidthOfTheGrid/theNumberOfColumns); 
      smallerBitmapImage.UriSource = fullPath; 
      smallerBitmapImage.EndInit(); 

      FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap(); 
      formatConvertedBitmap.BeginInit(); 
      formatConvertedBitmap.Source = smallerBitmapImage; 
      formatConvertedBitmap.DestinationFormat = PixelFormats.Gray16; 
      formatConvertedBitmap.EndInit(); 
      formatConvertedBitmap.Freeze(); 

      this.ImageSource = formatConvertedBitmap; 
+0

Quindi hai una griglia statica di immagini "conosciute"? Quanto sono grandi le immagini? –

+0

I futuri lettori che affrontano questo problema - vedi la mia risposta qui: http://stackoverflow.com/questions/9265725/wpf-bitmap-performance – Avi

+0

Stai usando le ombre? –

risposta

7

Sono stato in posizione simile (ho dovuto visualizzare le versioni di anteprima di immagini di grandi dimensioni in tempo reale).

Se si utilizza l'associazione dati per visualizzare le immagini, è possibile provare due cose:

  • Fai il legame OneWay (questo mi ha aiutato di più).
  • Provare a effettuare il binding async.

L'unica altra cosa è quella di ordinare le immagini - preferibilmente filo separato. Probabilmente potresti persino prescrivere immagini che potrebbero essere potenzialmente utilizzate in futuro mentre lo processor is idle - ad esempio se stai sviluppando un'applicazione simile a una mappa, puoi prescrivere immagini in aree nelle quali è più probabile che l'utente si muova.

+0

Grazie. Impostando tutti i binding in XAML su "{Binding ..., Mode = OneWay} sembra che le prestazioni dell'host siano migliorate da 8 a 6. L'impostazione del binding della raccolta ItemsControl su async potrebbe aver ridotto il ritardo a 5 secondi. , ma non siamo ancora lì ... – Avi

+0

@avi Si potrebbe anche provare a giocare con DecodePixelWidth http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.decodepixelwidth%28v = VS.100% 29.aspx Non sono sicuro se funziona con il binding però –

+0

È questo che intendevi con "prescale"? – Avi

1

Hai provato a sperimentare con diverse impostazioni della piattaforma di destinazione? Cioè x86 o AnyCPU.

+0

Grazie. Questo era davvero difettoso. Ora sono in esecuzione in x64. Tuttavia, l'host (cioè i7e, 24G RAM, SSD, 5850 HD) richiede ancora 8 secondi per passare alla successiva visualizzazione 11x11. – Avi

2

Si può provare la virtualizzazione per il controllo, aiuta notevolmente quando si caricano più immagini in listview. VirtualizingStackPanel

<ListBox.ItemsPanel> 
       <ItemsPanelTemplate> 
        <VirtualizingStackPanel Orientation="Vertical" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"/> 
       </ItemsPanelTemplate> 
      </ListBox.ItemsPanel> 

Se desidera utilizzare Viruatalization con l'involucro del pannello, v'è una certa dal Codeplex, Virtualalizing Wrappanel

So che è un vecchio thread, ma se qualcuno è ancora interessato.

1

Se si sta eseguendo su una VM, si stanno probabilmente riscontrando problemi con il rendering hardware (o almeno emulato-hardware) della grafica. WPF fa un uso pesante della grafica hardware e, su macchine con bassa capacità grafica, ne soffriranno le prestazioni.

È possibile aggirare il problema abilitando un'impostazione di registro che impedisce l'accelerazione hardware. Ciò è particolarmente utile su macchine che potrebbero aver sovrascritto le proprie capacità (dall'esperienza, ciò riguarda in particolare le VM e i chipset di grafica incorporati).

La chiave di registro necessaria è HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics\DisableHWAcceleration, a DWORD da impostare su 1. Nota che questo è a livello di sistema e interesserà tutte le app WPF: non impostarlo come parte della tua applicazione, ma usarlo nell'ambiente della tua macchina virtuale e assicurarti di eseguire nuovamente il test sull'hardware corretto prima di rilasciarlo.

Ulteriori informazioni here.

Problemi correlati