2010-06-30 22 views
6

I tienen alrededor de 45 imágenes decentemente grandes (alrededor de 680x1000) que necesitan ser cargado en un simple control de usuario (BackBorder redondeado con relleno, imagen, textblock, y 2 rectángulos secundarios) y luego se muestran en un WrapPanel. La virtualización no será de gran ayuda, ya que las imágenes serán visibles en la carga del programa.WPF: ¿Cómo cargar muchas imágenes grandes rápidamente en wrappanel?

Sé que dentro del inicio de BitmapImage puedo establecer el ancho decodepixel, lo que ayuda un poco, sin embargo id como cargarlos todos a tamaño completo ya que quiero poder cambiar el tamaño de las imágenes con un control deslizante sin perder calidad (esta parte funciona rápido en su mayor parte). Sé que una posibilidad sería establecer el ancho de decodificación para que sea un número que configuro, ya que el tamaño máximo visible podría ayudar.

He probado el enfoque de multiproceso que se encuentra en How do I load images in the background? (primera respuesta), sin embargo, hizo que el programa se necesita mucho más tiempo para cargar!

¿Alguna idea?

actual código de carga:

BitmapImage bmp = new BitmapImage(); 
bmp.BeginInit(); 
//bmp.DecodePixelWidth = 400; 
bmp.UriSource = new Uri(file.FullName); 
bmp.EndInit(); 
bmp.Freeze(); 
images.Add(bmp); 

Muestra código XAML:

 <Border x:Name="backBorder" Background="Black" Padding="2" Margin="3" CornerRadius="3,3,4,4" 
      BorderBrush="Black" BorderThickness="1" 
      MouseEnter="backBorder_MouseEnter" MouseLeave="backBorder_MouseLeave" MouseLeftButtonUp="backBorder_MouseLeftButtonUp" > 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition Height="16" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition Width="15" /> 
     </Grid.ColumnDefinitions> 
     <Image x:Name="imageBox" Stretch="Fill" Width="{Binding Path=ImageWidth, ElementName=me}" Height="{Binding Path=ImageHeight, ElementName=me}" /> 
     <Border x:Name="backRatingBorder" Grid.Column="1" Margin="3,0,0,0" BorderBrush="Blue" Background="White" BorderThickness="1"/> 
     <Border x:Name="frontRatingBorder" Grid.Column="1" Margin="3,0,0,0" BorderBrush="Blue" Background="LightBlue" BorderThickness="1" VerticalAlignment="Bottom" Height="50"/> 
     <TextBlock x:Name="textBlock" Grid.Row="1" Grid.ColumnSpan="2" TextAlignment="Center" Background="Transparent" Foreground="White" FontFamily="Segoe UI" FontWeight="SemiBold" FontSize="12" /> 
    </Grid> 
</Border> 

.

ACTUALIZACIÓN:

Bueno, yo terminé por lo que es más sensible mediante la ejecución del bucle de la imagen de carga en un solo trabajador de fondo. Después de cargar cada imagen, se llama a Dispacher.Invoke para crear el elemento de ajuste. Después de jugar con él por un tiempo, lo tengo para mostrar cada elemento tal como se crea en el mismo tiempo que se tomó antes.

Respuesta

1

Si está contento con el rendimiento general, solo con la carga de las imágenes, puede intentar this Multithreaded UI tutorial. logré que funcione con bastante facilidad, pero si está cargando todas las imágenes en un bucle, ganó ' t actualiza el visual hasta que hayas terminado de cargar todas las imágenes. Sin embargo, la IU responde durante este tiempo, ya que toda la carga está en un hilo separado.

Alternativly, si va a cargar todas las imágenes en un bucle entonces usted podría intentar un improved version of Windows Forms DoEvents method (desplácese hacia abajo para el ejemplo). Llamarás a esto después de cargar cada imagen y le dará a la UI la oportunidad de actualizarse a sí mismo (procesar la interacción del usuario, etc.). Este es el enfoque que utilicé al cargar mosaicos de mapas para mi proyecto y es más fácil que el primero.

+1

Creo que mi principal problema es la carga real de las imágenes del disco en la memoria. No estoy seguro de si hay algo que pueda arreglar realmente aquí, ¿verdad? Cargué todas las imágenes en una lista, luego genero todos los elementos de ajuste con referencias a las imágenes de mapa de bits de la lista. Puedo borrar todos los elementos secundarios y volver a crearlos bastante rápido, pero la carga en sí tarda varios segundos. Probé un ciclo Parallel.For para cargar las imágenes a la lista, pero causó que se cargaran mucho más despacio, probablemente debido al acceso asíncrono al disco. – user380527

Cuestiones relacionadas