在wpf中加载大量图像

本文关键字:图像 加载 wpf | 更新日期: 2023-09-27 18:03:45

我有大量的图片需要在我的wpf应用程序中加载。我尝试了一个BackgroundWorker,但它不能创建图像显示的切换按钮。

有没有更好的方法来加载大量的图像?它们必须是可选择的,因为用户可以选择图像。

这是我目前为止的一小部分代码:

<WrapPanel Name="mFolderImages">
    <ToggleButton Width="150" Margin="5" Style="{StaticResource ImageList}">
         <ToggleButton.Content>
              <Image Source="/Managment;component/images/example.png" />
         </ToggleButton.Content>
    </ToggleButton>
</WrapPanel>
private void GetFolderImagesThreadFinished(object sender, RunWorkerCompletedEventArgs e) {
        if (e.Result != null && e.Result is List<BitmapImage>) {
            List<BitmapImage> images = (List<BitmapImage>)e.Result;
            foreach (var image in images) {
                Image img = new Image();
                img.Source = image;
                img.Margin = new Thickness(5);
                ToggleButton btn = new ToggleButton();
                btn.Content = img;
                btn.Width = 150;
                btn.Margin = new Thickness(5);
                btn.IsEnabled = true;
                btn.Click += ChangeSelectedImage;
                btn.Style = this.FindResource("ImageList") as Style;
                mFolderImages.Children.Add(btn);
            }
        }
        mProgress.Visibility = Visibility.Collapsed;
        mFolderImages.IsEnabled = true;
    }
    private void GetFolderImagesThread(object sender, DoWorkEventArgs e) {
        string imagePath = Config.GetValue("ImagePath");
        if (!Directory.Exists(imagePath)) return;
        string[] files = Directory.GetFiles(imagePath);
        int progress = 0;
        List<BitmapImage> images = new List<BitmapImage>();
        foreach(var file in files) {
            if (file.EndsWith(".jpg") || file.EndsWith(".png")) {
                try {
                    BitmapImage bmp = new BitmapImage();
                    bmp.BeginInit();
                    bmp.UriSource = new Uri(file, UriKind.Absolute);
                    bmp.EndInit();
                    bmp.Freeze();
                    images.Add(bmp);
                } catch (Exception ex) {
                    Console.Write(ex.Message);
                }
            }
            ++progress;
            mThread.ReportProgress((int)((progress / (float)files.Length) * 100));
        }
        e.Result = images;
    }

在wpf中加载大量图像

为所有图像创建一个列表框,为图像创建一个可观察的集合。我不会使用图像,但会为图像创建一个分辨率较低的缩略图。
图像的每个viewModel将使用视图模型的数据模板来显示,该数据模板将显示缩略图。
还可以在这里快速查看图像的异步加载c#中异步加载图像

<ListBox ItemsSource="{Binding ImagesCollection}" 
   SelectedIndex="0">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Image Source="{Binding}"/> <!--bind to the field of the tumbnail using a converter if needed
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

好的,我知道了。

使用xaml中的Listbox, ItemsPanel中的Wrappanel和ItemTemplate中的图像。

然后在代码中,我使用BackgroundWorker来加载和调整图像大小,并使用reportProgress将其添加到集合中。

<ListBox ItemsSource="{Binding Path=ImagesCollection, IsAsync=True}" SelectedIndex="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
   <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
           <WrapPanel IsItemsHost="True" />
      </ItemsPanelTemplate>
   </ListBox.ItemsPanel>
   <ListBox.ItemTemplate>
       <DataTemplate>
          <Image Width="150" Height="150"  Source="{Binding}" />
       </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>
private void LoadImageProgress(object sender, ProgressChangedEventArgs e) {
        if (e.UserState != null && e.UserState is BitmapImage) {
            ImagesCollection.Add((BitmapImage)e.UserState);
        }
    }
    private void LoadImageThread(object sender, DoWorkEventArgs e) {
        string imagePath = Config.GetValue("ImagePath");
        if (!Directory.Exists(imagePath)) return;
        string[] files = Directory.GetFiles(imagePath);
        foreach (var file in files) {
            if (file.EndsWith(".jpg") || file.EndsWith(".png")) {
                var img = new Bitmap(file);
                float scale = Math.Min(150 / (float)img.Width, 150 / (float)img.Height);
                var bmp = new Bitmap(150, 150);
                var graph = Graphics.FromImage(bmp);
                var scaleWidth = (int)(img.Width * scale);
                var scaleHeight = (int)(img.Height * scale);
                graph.DrawImage(img, new System.Drawing.Rectangle((150 - scaleWidth) / 2, (150 - scaleHeight) / 2, scaleWidth, scaleHeight));
                BitmapImage retImg = new BitmapImage();
                using (MemoryStream mem = new MemoryStream()) {
                    bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Bmp);
                    mem.Position = 0;
                    retImg.BeginInit();
                    retImg.StreamSource = mem;
                    retImg.CacheOption = BitmapCacheOption.OnLoad;
                    retImg.EndInit();
                    retImg.Freeze();
                }
                mThread.ReportProgress(0, retImg);
                if (mThread.CancellationPending) return;
                //Thread.Sleep(1000);
            }
        }
    }