【问题标题】:WPF: How to load lots of large images fast into wrappanel?WPF:如何将大量大图像快速加载到包装面板中?
【发布时间】:2011-03-10 08:50:44
【问题描述】:

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

我知道在 BitmapImage init 内部我可以设置 decodepixel 宽度,这确实有点帮助,但是我喜欢将它们全部加载为全尺寸,因为我希望能够使用滑块调整图像大小而不会损失质量(这个大部分工作速度很快)。我知道一种可能性是将 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 以创建包装项目。玩了一段时间后,我让它显示每个项目,因为它是在之前的同一时间创建的。

【问题讨论】:

    标签: c# wpf image wrappanel


    【解决方案1】:

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

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

    【讨论】:

    • 我认为我的主要问题是将图像从磁盘实际加载到内存中。我不确定这里是否有什么我可以真正解决的问题,是吗?我将所有图像加载到列表中,然后生成所有包装项目,并引用列表中的 BitmapImages。我可以清除所有 wrap 孩子并很快重新创建它们,但加载本身需要几秒钟。我尝试了一个 Parallel.For 循环将图像加载到列表中,但它导致它们加载速度很慢,可能是由于异步磁盘访问。
    猜你喜欢
    • 2020-07-20
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    相关资源
    最近更新 更多