2012-02-13 5 views
8

Sto cercando di capire perché le mie immagini non sono scattanti, quindi ho creato un campione per testare le prestazioni WPF. Ho usato un timer per calcolare per quanto tempo il mio gestore di eventi "display images" è stato eseguito, e ho usato un cronometro per misurare il tempo necessario per far apparire le immagini sullo schermo. La linea di fondo: quando si visualizzano immagini 100, 1600, 2500 e 3600, WPF ha impiegato 2, 9, 12 e 16 secondi dopo il il mio codice aveva finito di visualizzare le immagini sullo schermo. Quindi mi sento impotente: sembra che non possa migliorare il mio codice per far apparire le immagini più velocemente - ho bisogno di fare qualcosa con WPF!Prestazioni bitmap WPF

Quindi la mia domanda è: Che cosa devo fare in modo diverso per rendere le immagini visualizzate più velocemente?


La configurazione di prova è semplice:

La finestra contiene una griglia. Dopo che il pulsante "test" viene cliccato, riga e di colonna sono definizioni added.Then un'immagine viene aggiunta a ciascuna cella della griglia come segue:

  var image = new Image(); 
      image.BeginInit(); 
      image.Name = ImageNameFromCell(theRow, theColumn); 
      image.Stretch = Stretch.None; 
      image.HorizontalAlignment = HorizontalAlignment.Center; 
      image.VerticalAlignment = VerticalAlignment.Center; 
      RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.LowQuality); 
      image.EndInit(); 

      theGrid.Children.Add(image); 

Infine, la fonte di ogni immagine è impostata su un bitmap: un'immagine in scala di grigi già ridimensionata alla dimensione stimata dello schermo. La bitmap viene generata come segue:

  var smallerBitmapImage = new BitmapImage(); 
      smallerBitmapImage.BeginInit(); 
      smallerBitmapImage.DecodePixelWidth = (int)(theImageWidth); 
      smallerBitmapImage.UriSource = theUri; 
      smallerBitmapImage.CacheOption = BitmapCacheOption.None; 
      smallerBitmapImage.EndInit(); 

      //BitmapFrame bitmapFrame = BitmapFrame.Create(this.FullPath); 

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

Quindi, sono alla fine del mio ingegno. Le immagini appaiono con un ritardo notevole e sembra fuori dal mio controllo. Cosa posso fare?

risposta

3

Che sembra aver fatto la differenza è l'impostazione opzione di cache dell'immagine per OnLoad

smallerBitmapImage.CacheOption = BitmapCacheOption.OnLoad;

Questo ha spostato il lavoro sul mio gestore di eventi, quindi ora posso utilizzare il pre-recupero per farlo in background.

3

Realmente vedi tutte quelle immagini allo stesso tempo? In caso contrario, è possibile utilizzare alcuni ItemsControl con un pannello di virtualizzazione in modo che vengano visualizzate solo le immagini in vista. (Parlando di pannelli, la configurazione attuale potrebbe anche essere sostituito con un ItemsControl che utilizza un UniformGrid come panel)

Si potrebbe anche provare a scrivere un decoder migliore, che probabilmente è uno sforzo sprecato.

+0

Grazie per la risposta, H.B. Sì, desidero vedere tutte quelle immagini allo stesso tempo. I casi 1600, 2500 e 3600 erano per il test, quindi ho potuto misurare facilmente il ritardo di WPF con la lancetta dei secondi di un orologio, ma direi che 400 immagini sono un numero che vorrei supportare. E la sottostima del "decodificatore migliore", pensavo che la decodifica fosse già stata eseguita nel codice "smallBitmapImage" qui sopra, cioè nel mio codice e non durante il tempo in cui WPF fa quello che fa dopo che il mio gestore di eventi ritorna, che è il momento in cui sto cercando di abbreviare ... – Avi

+1

@Avi: Oh, giusto, poiché i file sono presumibilmente locali, la decodifica può avvenire in modo sincrono ma non sono sicuro degli interni; dato che la conversione non genera eccezioni, questa ipotesi sembra praticabile. Se questo si riduce al puro tempo di rendering, potresti davvero essere in una situazione di bind, poiché sembra che tu stia già facendo tutto ciò che potrebbe accelerare le cose dalla decodifica a una dimensione più piccola per evitare il ridimensionamento. Non so cos'altro potresti fare qui :( –