用高分辨率图像替换低分辨率图像

时间:2014-09-25 11:06:35

标签: wpf image backgroundworker bitmapimage

我必须同时以高分辨率(每个约5 MB)显示~150张图像。问题是需要大量时间同时加载所有这些图像。因此,我想在开始时显示低分辨率图像,同时在背景中加载真正的高分辨率图像。然后,当他们准备好切换它们。

2 个答案:

答案 0 :(得分:0)

我不打扰所有的C#代码。相反,我只使用集合控件和文件路径集合。试试这个例子:

<ListBox ItemsSource="{Binding FilePaths}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}" Width="250" Stretch="Uniform" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

...

private ObservableCollection<string> filePaths = new ObservableCollection<string>();
public ObservableCollection<string> FilePaths
{
    get { return filePaths; }
    set { filePaths = value; NotifyPropertyChanged("FilePaths"); }
}

...

FilePaths = new ObservableCollection<string>(Directory.GetFiles(
    Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "*.png"));

答案 1 :(得分:-1)

过了一会儿,我最终得到了这个解决方案。首先,我加载低分辨率图像,然后将它们添加到网格中:

foreach (var extElem in ElemList)
{
   IdImage img = new IdImage();
   img.Id = extElem.ImageID;
   img.CollectionId = extElem.CollectionID;
   BitmapImage bi = new BitmapImage();
   bi.BeginInit();
   bi.UriSource = new Uri(extElem.Url, UriKind.Absolute);
   bi.DecodePixelWidth = 200; //If you want to further reduce the image size (and load time)
   bi.EndInit();
   img.Source = bi;
   grid.Children.Add(img);

   _imgList.Add(img);
}

然后我开始后台操作来加载高分辨率图像并更改位图的来源:

BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += (s, args) =>
{
    int i = 0;
    foreach (var extElem in _imgList)
    {
        String url = extElem.HighResImageUri;
        Image img = _imgList.ElementAt(i);

        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.UriSource = new Uri(url, UriKind.Absolute);
        bi.EndInit();
        bi.Freeze();

        Dispatcher.BeginInvoke((Action)(() =>
        {
            img.Source = bi;
        }));
    }
    i++;
}
bgw.RunWorkerAsync();