Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

WPF image gallery

Îåêßíçóå áðü ôï ìÝëïò DaltonGR. Τελευταία δημοσίευση από το μέλος DaltonGR στις 11-07-2013, 15:21. Υπάρχουν 3 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  29-06-2013, 10:08 73010

    WPF image gallery

    Καλημέρα,

    Εχω φτιάξει μια εφαρμογή που φορτώνει εικόνες απο τον σκληρό δίσκο με μια απλή εφαμρογή WPF, το πρόβλημα είναι ότι όταν οι εικόνες έχουν ανάλυση 1500χ1500 και άνω καθυστερεί να τις φορτώσει, και φαίνεται ότι η εφαρμογή δεν κάνει τίποτα. Υπάρχει κάποιος τρόπος η διαδικασία φορρτώματος των εικόνων να γίνει πιό γρήγορη. Παρακάτω είναι ο κώδικας XAML της αρχική φόρμας.

    <ListBox Name="Images" ListBox.SelectionChanged="lstImagesChange_Click" Grid.Column="1" 

                     ScrollViewer.HorizontalScrollBarVisibility="Disabled" VirtualizingStackPanel.IsVirtualizing="True"

                     VirtualizingStackPanel.VirtualizationMode="Recycling" ScrollViewer.IsDeferredScrollingEnabled="True" >

                <ListBox.Resources>

                    <Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">

                        <Style.Triggers>

                            <Trigger Property="Orientation" Value="Vertical">

                                <Setter Property="Width" Value="20"/>

                                <Setter Property="Height" Value="Auto" />

                            </Trigger>

                        </Style.Triggers>

                    </Style>

                </ListBox.Resources>

                <ListBox.ItemsPanel>

                    <ItemsPanelTemplate>

                        <WrapPanel IsItemsHost="True" Orientation="Horizontal" FlowDirection="LeftToRight" />

                    </ItemsPanelTemplate>

                </ListBox.ItemsPanel>

                <ListBox.ItemTemplate>

                    <DataTemplate>

                        <Border BorderThickness="2" BorderBrush="#bb62d8" Background="Black" Width="200" Height="200" Margin="5,5,10,5" CornerRadius="10">

                            <Image Source="{Binding Path=Path, Converter={StaticResource UriToBitmapConverter}}" Tag="{Binding ImageID}" />

                        </Border>

                    </DataTemplate>

                </ListBox.ItemTemplate>

            </ListBox>

    και εδώ μια class που πειράζει τις εικόνες

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

            {

                BitmapImage bi = new BitmapImage();

                bi.BeginInit();

                bi.DecodePixelWidth = 100;

                //bi.DecodePixelHeight = 100;

                bi.CacheOption = BitmapCacheOption.OnDemand;

                bi.UriSource = new Uri( value.ToString() );

                bi.EndInit();


                //return ResizeImage(bi,250,250);

                return bi;

           }

    Ευχαριστώ εκ των προτέρων. 

  •  06-07-2013, 03:37 73027 σε απάντηση της 73010

    Απ: WPF image gallery

    Από ότι κατάλαβα η εφαρμογή επειδή φορτώνει τις εικόνες στο ίδιο thread με αυτό του UI φαίνεται πως κολλάει και δεν ανταποκρίνεται στους χειρισμούς του χρήστη.

    Αυτό είναι και το πιο σημαντικό πρόβλημα, όσο για την ταχύτητα φόρτωσης των εικόνων στην εφαρμογή δεν νομίζω ότι μπορείς να κάνεις και πολλά πράγματα. Κάνω μία κλήση να φορτώσω μία εικόνα και ανάλογα με το μέγεθός της θα πάρει κάποιο χρόνο, τι παραπάνω μπορώ να κάνω; Τίποτα λέω εγώ. Αυτό όμως που θα μπορούσες να κάνεις είναι να δείχνει η εφαρμογή στον χρήστη ότι κάτι κάνει.

    Υπάρχουν διάφοροι τρόποι για αυτό. Άλλοι πονάνε περισσότερο, γιατί συνήθως θα πρέπει να γίνουν αλλαγές στον κώδικα για να έχουμε multi threading και άλλες λιγότερο με την βοήθεια του binding στο WPF.

    Για την περίπτωσή σου, θα σου πρότεινα το PriorityBinding. Για πιο λόγο στο προτείνω. Θα μπορούσες να ορίσεις στο source του image ένα priority binding το οποίο θα έχει δύο bindings. Στο πρώτο θα κάνεις bind το thumbs collection των εικόνων που μπορεί να έχεις και στο δεύτερο το κανονικό μέγεθος των εικόνων. Οπότε όταν ξεκινάει η εφαρμογή να δείχνει αρχικά τα thumbs και ασύγχρονα από πίσω να φορτώνει τις εικόνες σε κανονική ανάλυση. Αν δεν έχεις thumbs μπορείς απλά να βάλεις ένα animation και όταν φορτωθεί η εικόνα να αλλαχθεί το animation με την εικόνα.

    Όλα αυτά μπορεί να ακούγονται ή να φαντάζουν δύσκολα όμως δεν είναι στο WPF. Για παράδειγμα θα έγραφα.

    <Image.Source>

    <PriorityBinding>
            <Binding Path="FullImg" IsAsync="True"/>
            <Binding Path="PleaseWaitImg" />
          </PriorityBinding>
    </Image.Source

    Πρόσεξε την χρήση του IsAsync που λέει στο Binding να ξεκινήσει νέο thread για το συγκεκριμένο binding και φυσικά ότι με την πρόταση αυτή οι αλλαγές στο πρόγραμμά σου περιορίζονται μόνο σε XAML.

    Όσο το πρώτο binding θέλει τον χρόνο του για να φορτώσει την εικόνα στο source του image θα γίνει bind το PleaseWaitImg. Όταν ολοκληρωθεί το πρώτο binding και φορτώσει την εικόνα, αυτόματα θα γίνει αυτό το current bind του source property. Νομίζω θα βρεις αρκετά παραδείγματα για άρθρα για τα PriorityBindings στο internet. Ελπίζω να σου έδωσα μία ιδέα για να ξεκινήσεις.

     

     

  •  08-07-2013, 10:54 73034 σε απάντηση της 73027

    Απ: WPF image gallery

    Εγώ θα ρώταγα πρώτα ΓΙΑΤΙ υπάρχει ο converter? Το Image.Source δέχεται απευθείας URIs, δεν υπάρχει λόγος να χρησιμοποιηθεί κάποιος converter.

    Το  πρόβλημα αυτή τη στιγμή είναι ότι ο converter παίρνει ένα Uri και φορτώνει την εικόνα σύγχρονα, στο UI thread με αποτέλεσμα να μπλοκάρει η εφαρμογή. 


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  11-07-2013, 15:21 73065 σε απάντηση της 73034

    Απ: WPF image gallery

    Ο converter υπάρχει διότι μετά απο ψάξιμο το έδιναν αρκετά forum για λύση, να πώ την αλήθεια σημαντική διαφορά δεν έχω δεί.
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems