Cargar Imagenes Thumnbail

El otro día haciendo una pequeña aplicación para ver la lista de fotos que tengo de mi hijo que os podéis imaginar que son miles en los casi tres años que tiene, vi que al cargarlos en un ListView me tardaba bastante, también lo achaque a que algunas fotos (la mayoría) son de mas de 5 MB.

Hacia una carga del las fotos de mi disco duro

 

 var fotos = from d in new DirectoryInfo(@"d:fotos").GetDirectories()
                        from f in d.GetFiles()
                        where f.Extension.Contains("JPG")
                        orderby d.Name
                        select new { ImagePath = f.FullName, dirName = d.Name };
            DataContext = fotos;

Yo utilizaba una ListView de este tipo

<ListView ItemsSource="{Binding}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding Path=ImagePath, Converter={StaticResource ImageConverter}}" /> 
                </DataTemplate> 
            </ListView.ItemTemplate> 
        </ListView>

Con el típico Converter de imágenes que ya hemos explicado

 public sealed class ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                return new BitmapImage(new Uri((string)value));
            }
            catch
            {
                return new BitmapImage();
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

La verdad es que tardaba bastante y además quería que se visualizase en formato thumbail,  me puse a buscar si habría alguna manera mas rápida de hacerlo y si hay, nos tenemos que basar en la clase BitmapImage. Esta clase tiene la propiedad DecodePixelWidth que obtiene o establece el ancho, en píxeles, en el que se decodifica la imagen, en este caso pasamos las imagenes a100 poxels que para un thumbail es mas que suficiente.

De manera que le  Converter pasaba a

public sealed class ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.DecodePixelWidth = 100;
            bi.CacheOption = BitmapCacheOption.OnLoad;
            bi.UriSource = new Uri(value.ToString());
            bi.EndInit();
            return bi;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

La carga era mucho mas rápida y eficiente, además de mostrar en el tamaño adecuado. Así que ya sabéis si queréis mostrar thumbails de imágenes utilizar esta propiedad.

Pero para poner una pega ese listbox me muestra por defecto una lista hacia abajo, si quisiera cambiar la propiedad ItemsPanelTemplate para poner un WrapPanel y me las muestre en horizontal que creéis que pasara? Probarlo os llevareis una sorpres(para probarlo utilizar mas de 1000 archivos una carga masiva) En el siguiente post lo contare

 

 

 

3 comentarios sobre “Cargar Imagenes Thumnbail”

  1. Ya lo explicarás con detalle, pero entiendo que habrás pasado de usar un “VirtualizingStackPanel” que usa el ListBox implícitamente a un WrapPanel que no virtualiza los objetos a renderizar y por tanto tardará siglos y posiblemente se quede sin memoria ^_^

    Para hacer algo así tendrías que virtualizar a nivel de “capa de datos” y paginar lo que cargas.

    En .NET 3.5 SP1 creo recordar que habían ampliado las opciones de virtualización y demás, si vas a hacer un post detallado sería interesante incluirlo, que con lo “nuevo” que es WPF ya vamos acarreando “verdades históricas” 🙂

  2. En efecto Pablo, el prblema que queria reflejar con el cambio a WrapPanel es el tema de la virtualización de datos que en SP1 en las listbox funciona nativamente como has comentado. Estoy preparando un post sobre la virtualizacion de datos pero creo que hasta septiembre no lo tendre llegan las vacaciones.

    Buen comentario Pablo 🙂

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *