Bilder rotieren mit C# – Bitmap.RotateFlip vs.Graphics-Object

Auf der Suche nach einer Funktion zum Rotieren von Bildern in C# bin ich auf folgenden Beitrag auf dotnet-snippets.de gestoßen: Bilder rotieren mit C#.
Neben der eigentlich vorgestellten Methode wurden in den Kommentaren noch 2 andere Methoden vorgestellt und die Frage in den Raum geworfen, welche Methode davon die schnellste sei. Da dies auch mein Interesse weckte, habe ich kurzerhand eine kleine Test-Applikation geschrieben, die die verschiedenen vorgestellten Funktionen auf Herz und Nieren ihre Geschwindigkeit überprüfen sollte.

Nach einigen Testläufen wurde klar, dass die eigentliche Funktion nicht geeignet war, da in ihr jedes Mal ein neues Bitmap Objekt erstellt wurde, was Unmengen an Speicher frisst. Somit wurde folgende Funktion aus den Tests ausgeschlossen.

public Bitmap rotateImage(Bitmap bitmap, float angle)
{
     Bitmap returnBitmap = new Bitmap(bitmap.Width, bitmap.Height);
     Graphics graphics = Graphics.FromImage(returnBitmap);
     graphics.TranslateTransform((float)bitmap.Width / 2, (float)bitmap.Height / 2);
     graphics.RotateTransform(angle);
     graphics.TranslateTransform(-(float)bitmap.Width / 2, -(float)bitmap.Height / 2);
     graphics.DrawImage(bitmap, new Point(0, 0));
     return returnBitmap;
}

Im Rennen blieb jedoch folgende, leicht veränderte, ebenfalls dem Graphics-Object basierende Funktion,

public Bitmap rotateImageUsi(Bitmap bitmap, float angle)
{
    using (Graphics graphics = Graphics.FromImage(bitmap))
    {
        graphics.TranslateTransform((float)bitmap.Width / 2, (float)bitmap.Height / 2);
        graphics.RotateTransform(angle);
        graphics.TranslateTransform(-(float)bitmap.Width / 2, -(float)bitmap.Height / 2);
        graphics.DrawImage(bitmap, new Point(0, 0));
    }
    return bitmap;
}

sowie die Bitmap-Class eigene RotateFlip Funktion.

public Bitmap rotateInternalFunction(Bitmap bitmap)
{
    bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
    return bitmap;
}

Zum Testen der Geschwindigkeit habe ich folgendes, komprimiertes Foto vom letzten Wochenende genommen.

Steinberg in Goslar
(Anklicken um zum Bild in Originalgröße zu gelangen.)

Dann habe ich diese Bild mit beiden Funktionen jeweils 10, 100, 250, 500, 1000, 5000 und 10000 mal um 180° rotiert und die Zeit für Ausführung der Funktionen gemessen.

int[] testruns = new int[]{10,100,250,500,1000,5000,10000};
Bitmap bmp = (Bitmap)Bitmap.FromFile(pic);
string result = string.Empty;

foreach (int x in testruns)
{

    DateTime s2 = DateTime.Now;
    for (int i = 0; i < x; i++)
    {
        rotateImageUsi(bmp, 180f);
    }
    DateTime e2 = DateTime.Now;

    DateTime s3 = DateTime.Now;
    for (int i = 0; i < x; i++)
    {
        rotateInternalFunction(bmp);
    }
    DateTime e3 = DateTime.Now;

    TimeSpan t2 = new TimeSpan(e2.Ticks - s2.Ticks);
    TimeSpan t3 = new TimeSpan(e3.Ticks - s3.Ticks);

    result += "Durchläufe: " + x.ToString() + "\r\n" +
            t2.TotalMilliseconds.ToString() + "\r\n" +
            t3.TotalMilliseconds.ToString() + "\r\n\r\n==========================\r\n";
}

Dabei kam ich zu folgenden Ergebnissen:

 Testdurchläufe Zeit in ms – Graphics-Object Zeit in ms – Bitmap.RotateFlip
10 640 23
100 5327 167
250 10955 409
500 18641 758
1000 35375 1343
5000 232421 7270
10000 448424 9734

Ausführungsgeschwindigkeit - Bilder rotieren in C#

Getestet habe ich das ganze auf meinem Laptop mit einem Intel Core i3 M330 Prozessor, 4GB Arbeitsspeicher, .Net-Framework 4 unter Windows 7.
Betrachtet man die Ergebnisse, so lässt sich sagen, dass die RotateFlip-Variante wesentlich schneller ist, was vor allem bei der Bearbeitung  von vielen Bildern zu Buche schlägt.
Einen Grund gibt es dennoch auf die Graphics Variante zurückzugreifen: Der frei wählbare Winkel im Gegenteil zu RotateFlip.

Solltet ihr nun auch Lust bekommen haben, könnt ihr euch meine Testumgebung hier als Visual Studio Projekt herunterladen und eure eigenen Tests durchführen. Über Kommentare würde ich mich wie immer natürlich sehr freuen.

Viele Grüße,
Raffi

Hinterlasse einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Sie dient nur dem Spamschutz.