WPF Images Performance

30/12/2008 - 18:34 von Boas Enkler | Report spam
Hallo

ich habe begonnen mich mit WPF zu beschàftigen.
Dazu habe ich eine kleine Beispiel applikation geschrieben, welche
alle Photos (JPG) eines Folders anzeigen soll.

Als Container habe ich sowohl das UniForm Grid als auch ein
Stackpanel verwendet.

Dazu lade ich die Images via BitmapImage in ein Image control und füge
diese als Childs in den Parent.

Nun dauert das aber für 10 Bilder fast 10 sekunden.

Die Bildgröße sind 1,5 MB und alle Bilder liegen lokal.

Der Code in der von mir geschriebenen Methode dauert < 1 sekunde. Nach
dem mein Stackfertig ist scheint aber das Stackpanel nachtràglich
etwas zu tun, was sich mir nicht erschließt.

Was mache ich falsch oder wie optimiere ich die performance?
Wie lade ich die images am besten asynchron ? Da anscheinend kein
aktueller Code von mir die Wartezeit wesentlich beeinflusst , weiß ich
auch nicht was ich da paralell ablaufen lassen könnte...

Hier noch der Code (achtung ist nur ein Testprogram und deswegen auch
Dirty!)


DirectoryInfo nf = new DirectoryInfo(@"Z:\2008\Hochzeit
\Standesamt");

FileInfo[] files = nf.GetFiles("*.jpg");


if (files != null && files.Length > 0)
{
BitmapImage img;
Image control;

this.target.BeginInit();
foreach (FileInfo nfo in files)
{

img = new BitmapImage(new Uri
(nfo.FullName,UriKind.Absolute));

control = new Image();
control.BeginInit();
control.Source = img;
control.Width = 64;
control.Height = 64;
this.target.Children.Add(control);
control.EndInit();


}

this.target.EndInit();

}
 

Lesen sie die antworten

#1 Elmar Boye
31/12/2008 - 10:56 | Warnen spam
Hallo Boas,

Boas Enkler schrieb:
ich habe begonnen mich mit WPF zu beschàftigen.
Dazu habe ich eine kleine Beispiel applikation geschrieben, welche
alle Photos (JPG) eines Folders anzeigen soll.



Schau Dir mal die Beispiele von Adam Nathan WPF Unleashed an,
deren Code unter <URL:http://www.adamnathan.net/wpf/>
als Download verfügbar sind.

Er verwendet in seinem - auch ansonsten empfehlenswerten - Buch,
ein PhotoGallery Beispielprogramm in verschiedenen Ausbaustufen.

control = new Image();
control.BeginInit();
control.Source = img;
control.Width = 64;
control.Height = 64;
this.target.Children.Add(control);




Und noch ein kleiner Alternativ-Vorschlag via ListBox unten dran.

Gruß Elmar

/// Window1.xaml

<Window x:Class="Wpf1.Window1"
xmlns="http://schemas.microsoft.com/winfx/...tion"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Photo ListBox">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>

<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal">
<Label Content="Verzeichnis:"
VerticalContentAlignment="Center" />
<TextBox x:Name="folderTextBox"
Width="192" Height="21" Margin="10,0"/>
<Button x:Name="addFolderButton"
Padding="5"
Content="Hinzufügen"
Click="addFolderButton_Click" />
</StackPanel>
<ListBox x:Name="photoListBox"
Margin="10"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Grid.Row="1" Grid.Column="0">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</Window>

\\\

/// Window1.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.IO;

namespace Wpf1
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}

private void addFolderButton_Click(object sender, RoutedEventArgs e)
{
string directory = folderTextBox.Text.Trim();
if (!Directory.Exists(directory))
return ;

foreach (string fileName in Directory.GetFiles(directory, "*.jpg"))
{
Image image = new Image();
image.Height = 64;

Uri uri = new Uri(fileName);
image.Source = new BitmapImage(uri);

ListBoxItem listBoxItem = new ListBoxItem();
listBoxItem.Padding = new Thickness(8);
listBoxItem.Content = image;

photoListBox.Items.Add(listBoxItem);
}
}
}
}

\\\

Ähnliche fragen