c# - WPF:如何将大量大图像快速加载到包装面板中?

标签 c# wpf image wrappanel

我有大约 45 张相当大的图像(大约 680x1000)需要加载到一个简单的用户控件中(带有填充、图像、文本 block 和 2 个边矩形的圆形背景),然后显示在包装面板中。虚拟化在这里并没有真正的帮助,因为图像在程序加载时都是可见的。

我知道在 BitmapImage init 内部我可以设置 decodepixel 宽度,这确实有点帮助,但是我喜欢将它们全部加载为完整尺寸,因为我希望能够使用 slider 调整图像大小而不会降低质量(这部分在大多数情况下工作得很快)。我知道一种可能性是将 decodewidth 设置为某个数字,我将其设置为最大可视大小可能会有所帮助。

我尝试了 How do I load images in the background? 中的多线程方法(第一个答案),但是它导致程序加载时间更长!

有什么想法吗?

当前加载代码:

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

示例 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>

.

更新:

好吧,我最终通过在单个后台工作程序中运行加载图像循环来提高响应速度。加载每个图像后,调用 Dispacher.Invoke 来创建包装项。玩了一会儿后,我让它显示了每个项目,因为它是在与之前相同的时间内创建的。

最佳答案

如果您对整体性能感到满意,只是图像加载,您可以尝试 this Multithreaded UI tutorial.我设法让它很容易地工作,但是如果你在循环中加载所有图像,它不会更新视觉效果,直到你完成所有图像的加载。然而,UI 在此期间是响应式的,因为所有加载都在单独的线程上进行。

或者,如果您在循环中加载所有图像,那么您可以尝试 improved version of Windows Forms DoEvents method (向下滚动到示例)。你会在加载每张图片后调用它,它会让 UI 有机会 self 更新(处理用户交互等)。这是我在为我的项目加载 map 图 block 时使用的方法,比第一种方法更容易。

关于c# - WPF:如何将大量大图像快速加载到包装面板中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3153458/

相关文章:

c# - 如何将焦点设置到已经处于运行状态的应用程序?

c# - 如何确定谁拥有我的应用程序退出时仍在运行的工作线程?

jquery - 有没有办法动画显示:none?

c# - 在没有第 3 方库的情况下使用 C# .net 3.0 或更低版本将 pdf 转换为 tiff?

java - GImage 找不到我的图像

flutter - 显示数据库中的图像,该图像在 flutter 的路径中具有反斜杠而不是斜杠

c# - 打开 SQL 连接时拒绝访问

c# - 需要调试从客户端计算机请求的 Web API 服务 - 需要帮助,我该怎么做?

c# - Bing map 绑定(bind)问题

wpf - 在 FullRow 选择模式下禁用 DataGrid 当前单元格边框