Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Performance von Blend-Effekt von einem Bild ins andere verbessern
kleinrechner
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

Performance von Blend-Effekt von einem Bild ins andere verbessern

beantworten | zitieren | melden

Hallo,
würde von einem Bild in ein anderes Bild überblenden lassen,
habe dafür aktuell folgende Funktion entwickelt:



            var stepCount = 75;
            return Enumerable.Range(0, stepCount).Select(x => GetImage(x, stepCount, secondaryImageMedia, primaryImageMedia));


        private Bitmap GetImage(int x, int stepCount, Bitmap sourceImage, Bitmap targetImage)
        {
            var destination = new Bitmap(Math.Max(sourceImage.Width, targetImage.Width), Math.Max(sourceImage.Height, targetImage.Height));
            using (var graphics = Graphics.FromImage(destination))
            {
                using (var attributes = new ImageAttributes())
                {
                    //create a color matrix object  
                    var matrix = new ColorMatrix();

                    //set the opacity  
                    matrix.Matrix33 = 1 - ((float)x / (float)stepCount);

                    attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                    graphics.DrawImage(sourceImage, new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), 0, 0, destination.Width, destination.Height, GraphicsUnit.Pixel, attributes);
                }

                using (var attributes = new ImageAttributes())
                {
                    //create a color matrix object  
                    var matrix = new ColorMatrix();

                    //set the opacity  
                    matrix.Matrix33 = (float)x / (float)stepCount;

                    attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                    graphics.DrawImage(targetImage, new Rectangle(0, 0, targetImage.Width, targetImage.Height), 0, 0, destination.Width, destination.Height, GraphicsUnit.Pixel, attributes);
                }

                graphics.Save();
            }

            return destination;
        }



Es funktioniert zwar und gibt mir das gewünschte ergebnis zurück, benötigt aber dafür ca. 5 sek.
Da ich sonst auch eher BusinessAnwendung, hab ich von Grafik-Bearbeitung leider ziemlich wenig Erfahrung, evlt sieht die BestPractice ja auch ganz anders aus.
Oder einen Tipp geben, wie ich das schneller machen kann oder parallelisieren kann, ohne dass ich Fehler bekomme, dass das Bild bereits in Verwendung ist.


Vielen Dank

cu
Christian
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15955

beantworten | zitieren | melden

Naja, dann mach das, was man in so einem Fall eben tut: schmeiss den Performance Profiler, der in Visual Studio integriert ist, an und lass Dir den Hot Path zeigen.
Dann siehst auch die Stelle, die Zeit frisst.

Ich vermute, dass Dein DrawImage langsam sein wird; GDI+ ist eben halt auch nicht gerade die performanteste Art und Weise - und das wird eben hier verwendet.
Letzten Endes kann aber jeder hier nur raten.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
kleinrechner
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

beantworten | zitieren | melden

Zitat
Ich vermute, dass Dein DrawImage langsam sein wird; GDI+ ist eben halt auch nicht gerade die performanteste Art und Weise - und das wird eben hier verwendet.
Letzten Endes kann aber jeder hier nur raten.
Deshalb hatte ich ja gefragt, weil ich, wie gesagt, nicht so viel Erfahrung in Bildbearbeitung hab, evlt hat jemand einen besser Methode, wie man das umsetzen kann.

cu
Christian
private Nachricht | Beiträge des Benutzers
Gimmick
myCSharp.de - Member



Dabei seit:
Beiträge: 128

beantworten | zitieren | melden

Schau mal hier für das Prinzip:
https://code.msdn.microsoft.com/windowsapps/Blending-Bitmap-2922c196

Wenn das Überblenden nach Schrittzahl gehen soll, könnte man die Schrittweite pro Pixel getrennt hinterlegen und so noch minimal Rechenzeit sparen, soll das Überblenden nach Zeit gehen, müsste man die Schrittweite zumindest nach dem ersten Schritt anpassen.

Ansonsten könnte man auch hier wieder ein bissl lügen und betrügen und z.B. nur jeden zweiten Pixel abwechselnd ändern.
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5973
Herkunft: Leipzig

beantworten | zitieren | melden

Überblendungen können auch auf den schwächsten Geräten in Echtzeit berechnet und angezeigt werden. Zur Not mit GPU-Unterstützung.

Das, was du da zeigst, kann ich aber nicht nachvollziehen. Schau dir doch mal Implementierungen von Bibliotheken an, die sowas schon machen.
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
kleinrechner
myCSharp.de - Member



Dabei seit:
Beiträge: 16

Themenstarter:

beantworten | zitieren | melden

Falls es jemanden interessiert, hab es aktuell wie folgt gelöst, das funktioniert auch, wie gewünscht:



        private void Timer_Tick(object sender, EventArgs e)
        {
            if (alpha ≤ 1)
            {
                using (var oldImage = pictureBox1.Image)
                {
                    var destinationImage = new Bitmap(sourceImage);
                    using (var graphics = Graphics.FromImage(destinationImage))
                    {
                        using (var attributes = new ImageAttributes())
                        {
                            //create a color matrix object  
                            var matrix = new ColorMatrix();

                            //set the opacity  
                            matrix.Matrix33 = alpha;

                            attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                            graphics.DrawImage(targetImage, new Rectangle(0, 0, targetImage.Width, targetImage.Height), 0, 0, destinationImage.Width, destinationImage.Height, GraphicsUnit.Pixel, attributes);
                        }
                    }
                    pictureBox1.Image = destinationImage;
                    alpha += 1 / (float)75;
                }
            }
            else
            {
                timer.Stop();
            }
        }
private Nachricht | Beiträge des Benutzers
Gimmick
myCSharp.de - Member



Dabei seit:
Beiträge: 128

beantworten | zitieren | melden

Gute Sache, danke fürs Posten
private Nachricht | Beiträge des Benutzers