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.
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