Laden...

TiffDecoder beschleunigen

Erstellt von bl4ckY vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.430 Views
B
bl4ckY Themenstarter:in
193 Beiträge seit 2009
vor 13 Jahren
TiffDecoder beschleunigen

Hallo,

habe eine kurze Frage. Ich nutze den TiffBitmapDecoder um ein Multipage Tiff aus einander zubröseln. Die jeweiligen Bilder packe ich in eine Listbox. Die wieder rum in ein Tabitem. Problem ist das dass ganze etwas lahm ist. Heißt wenn ich das Tab anklicke braucht er etwa 0.5 Sekunden bis das ganze geöffnet ist.

Das ganze sollte aber möglichst ohne merkliche Verzögerungen von statten gehen, da es eine zeitkritische Client Server Applikation ist.

Stream imageStreamSource = new FileStream(task.path + filename, FileMode.Open, FileAccess.Read, FileShare.Read);
TiffBitmapDecoder TiffDecoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
return TiffDecoder;

Mit den Options kann ich das ganze zwar verlagern, sprich entweder ist er beim Öffnen des Tabs langsam oder beim Erstellen. Sollte aber nach Möglichkeit beides schnell sein. Gibts da vielleicht noch einen Trick um das ganze etwas aufzumotzen?

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo bl4ckY,

sprich entweder ist er beim Öffnen des Tabs langsam oder beim Erstellen.

nutze die Zeit dazwischen (Stichwort: Thread/BackgroundWorker)

herbivore

B
bl4ckY Themenstarter:in
193 Beiträge seit 2009
vor 13 Jahren

Danke herbivore,

ich muss gestehen ich wüsste nicht wo ich das machen sollte. Meinst du beim Dekodieren?

        private void CreateImagePreviewAndShow(Task task)
        {
            try
            {
                foreach (string filename in task.message)
                {
                    List<BitmapSource> imageList = new List<BitmapSource>();
                    TiffBitmapDecoder decoder = DecodeImage(task, filename);

                    CreateListOfClones(imageList, decoder);
                    CreateTabItemsWithCloneList(filename, imageList);
                }
                tabControl.SelectedItem = tabControl.Items.GetItemAt(0);
            }
            catch (Exception)
            {
                ShowProcessingErrorBox();
            }
        }

        private static void ShowProcessingErrorBox()
        {
            MessageBox.Show(...);
        }

        private void CreateTabItemsWithCloneList(string filename, List<BitmapSource> imageList)
        {
            if (LayoutDirection == Direction.HORIZONTAL)
            {
                CreateHorizontalImageControl(filename, imageList);
            }
            else
            {
                CreateVerticalImageControl(filename, imageList);
            }
        }

        private void CreateVerticalImageControl(string filename, List<BitmapSource> imageList)
        {
            using (ImageShowPreviewVertical newImageShow = new ImageShowPreviewVertical())
            {
                newImageShow.newImage(imageList);
                tabControl.Items.Add(new TabItem()
                {
                    Header = filename.Replace(".TIF", ""),
                    Content = newImageShow
                });
            }
        }

        private void CreateHorizontalImageControl(string filename, List<BitmapSource> imageList)
        {
            using (ImageShowPreviewHorizontal newImageShow = new ImageShowPreviewHorizontal())
            {
                newImageShow.newImage(imageList);
                tabControl.Items.Add(new TabItem()
                {
                    Header = filename.Replace(".TIF", ""),
                    Content = newImageShow
                });
            }
        }

        private static void CreateListOfClones(List<BitmapSource> imageList, TiffBitmapDecoder decoder)
        {
            foreach (BitmapSource bitmapSource in decoder.Frames)
            {
                imageList.Add(bitmapSource.Clone());
            }
        }

        private static TiffBitmapDecoder DecodeImage(Task task, string filename)
        {
                Stream imageStreamSource = new FileStream(task.path + filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.OnDemand);
                return decoder;
        }

Vielleicht findet ja jemand einen ruhigen Moment und kann kurz drüber sehen und vielleicht ein paar Tipps geben. Der Fehler kann ja auch an einer anderen Stelle liegen an die atm garnicht denke.

B
bl4ckY Themenstarter:in
193 Beiträge seit 2009
vor 13 Jahren

Ich muss das nochmal hochstubsen. Nach unzähligen versuchen denke ich das ich es einfach nicht schneller bekomme. Vielleicht hat ja einer einen Moment Zeit und Langeweile um mal drüber zusehen. Meine bisherigen Threading versuche haben das ganze eher verlangsamt also beschleunigt 😕

1.820 Beiträge seit 2005
vor 13 Jahren

Hallo!

Sowoahl auf CodePlex als auch CodeProject gibt es zahlreiche Tiff-Libraries und -Demos. Evtl. arbeitet eine davon schneller als deine Komponente.

Nobody is perfect. I'm sad, i'm not nobody 🙁

F
10.010 Beiträge seit 2004
vor 13 Jahren

Meine bisherigen Threading versuche haben das ganze eher verlangsamt also beschleunigt

Dann solltest du uns erzählen was du da "falsch" gemacht hast.

B
bl4ckY Themenstarter:in
193 Beiträge seit 2009
vor 13 Jahren

In erster Linie ist mein Problem, dass ich nicht weiß welchen Teil ich mit Threading beschleunigen könnte. Es macht ja eigentlich nur Sinn das ganze in verschiedene Thread aufzuteilen wenn ich mehrere Operationen gleichzeitig machen kann.

private void CreateImagePreviewAndShow(Task task)
        {
            try
            {
                foreach (string filename in task.message)
                {
                    Thread thread = new System.Threading.Thread(
                    new ThreadStart(delegate
                    {
                        this.Dispatcher.BeginInvoke(new Action(delegate()
                        {
                            List<ImageSource> imageList = new List<ImageSource>();
                            TiffBitmapDecoder decoder = DecodeImage(task, filename);
                            CreateListOfClones(imageList, decoder);
                            CreateTabItemsWithCloneList(filename, imageList);
                        }));
                    }));
                    thread.Start();
                }
            }
            catch (Exception)
            {
                ShowProcessingErrorBox();
            }
        }

Das habe ich hier gemacht, leider ohne erkennbare Verbesserung.

S
753 Beiträge seit 2006
vor 13 Jahren

Du solltest erst mal Benchmarken, wo die Performance Lücke auftritt.
Vielleicht geht es schneller, wenn du die Elemente in einem Pool verwaltest oder bei der erstmaligen Benutzung cached.
Da sollte man aber auf jeden Fall das Speicherverhalten zur Laufzeit beobachten

Life is a short

B
bl4ckY Themenstarter:in
193 Beiträge seit 2009
vor 13 Jahren
private static TiffBitmapDecoder DecodeImage(Task task, string filename)
        {
                Stream imageStreamSource = new FileStream(task.path + filename, FileMode.Open, FileAccess.Read);
                TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.OnLoad);
                return decoder;
        }

Also das hier ist eindeutig der Teil der mein Programm bremst. Auch verständlich da hier auch am meisten geschiet. Aber bei einem 170kb MultiTiff mit 2 Seiten etwa 2Sekunden zu rattern. Das ist wirklich zu viel.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo bl4ckY,

Thread thread = new System.Threading.Thread(  
                    new ThreadStart(delegate  
                    {  
                        this.Dispatcher.BeginInvoke(new Action(delegate()  

Das geht - trotz der Schleife drum herum - schon sehr in Richtung [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) Abschnitt "Die Falle".

herbivore

B
bl4ckY Themenstarter:in
193 Beiträge seit 2009
vor 13 Jahren

Ja den Teil habe ich auch bereits wieder entfernt weil einfach die Steigerung viel zu gering war. Danke für den Hinweis.