2009-06-12 8 views
4

Wenn ich einen Kachel-basierten Karteneditor in C# mache, tendiere ich dazu, über die X-, Y-Achsen zu iterieren und Graphics.DrawImage() aufzurufen, um eine einzelne Kachel von einer Kachel-Bitmap auf eine Karten-Bitmap zu setzen. Dieser Vorgang dauert einige Sekunden. Ich mache das also nur einmal, wenn ich eine neue Map lade oder das Tileset ändere. Alle Bearbeitungen von dort sind relativ schnelle Blitze nur der bearbeiteten Kachel.Könnte dieser Fliesenblitter schneller werden?

Jetzt saß ich heute früher zurück und dachte über meine Möglichkeiten nach. Graphics.DrawImage() ist das einzige von den dreien (die anderen sind DrawImageUnscaled und DrawImageUnscaledAndCropped (?)), Die die Spezifikation eines Quellursprungs ermöglichen. DrawImageUnscaled() war viel, viel schneller, aber immer von der oberen linken Ecke der Quell-Bitmap geblisted.

In scharfem Kontrast zu den Geschwindigkeiten von Quickbasic PSET gegen POKEing des Videospeicher oder VB6 der PSet gegen WinAPI des SetPixel, eine einfache Get/SetPixel Schleife war so schnell wie ein DrawImageUnscaled Anruf, aber das Zuschneiden tat das nur DrawImage würde sonst tun.

Das ist schnell genug für jetzt, aber ich frage mich, wie etwas wie direkte Bildbearbeitung es noch mehr beschleunigen könnte? Etwas mit LockBits vielleicht, eine Funktion, über die ich so gut wie nichts weiß?

+1

Dies ist nicht wirklich die Antwort auf Ihre Frage, aber Sie können die Geschwindigkeit des DrawImage erhöhen, indem Sie das gesamte Rechteck des Bildes definieren -> X, Y, Width, Height. In meinem Test erreichte ich eine Beschleunigung von ca. 20%. –

Antwort

1

Es ist eine ausgezeichnete Lösung für diesen an .. How to manipulate images at the pixel level in C#

Wenn Sie den LockBits Weg gehen tun könnten Sie ein Follow-up mit den Geschwindigkeitsdifferenzen stellen.

+0

Ich werde gleich nachsehen und sehen, was ich mir vorstellen kann. Vielen Dank. – Kawa

1

Software Blitting scheint ein schwerer Engpass zu sein. Ich würde ernsthaft vorschlagen, Hardware-beschleunigtes Zeichnen für eine solche Aufgabe zu untersuchen.

+0

Zumindest der Hals wurde deutlich breiter. – Kawa

1

eine einfache Get/SetPixel Schleife war so schnell als DrawImageUnscaled Anruf

Dann sind Sie auf jeden Fall etwas falsch zu machen. Die GetPixel und SetPixel Methoden haben ziemlich viel Overhead, mit einer der DrawImage Methoden sollte etwas 100 mal schneller sein (außer vielleicht, wenn Ihre Kacheln sehr klein sind, wie 2x2 Pixel).

Im Gegensatz zu seinem Namen zeichnet die DrawImageUnscaled-Methode nicht ohne Größenänderung. Stattdessen verwendet es die PPI-Einstellungen der Bilder, um sie auf die gleichen Maße zu skalieren. Das bedeutet, wenn Sie eine Bitmap mit der Einstellung 100 PPI haben und eine Bitmap mit der Einstellung 50 PPI darauf zeichnen, wird die Größe auf die doppelte Größe geändert. Wenn Sie die Bilder in unveränderter Größe zeichnen, können Sie die Qualitätseinstellungen im Objekt Graphics ändern, um die Geschwindigkeit zu optimieren. Sie können zum Beispiel die Eigenschaft InterpolationMode auf NearestNeighbor setzen, damit keine Interpolation ausgeführt wird.

Eine Alternative zum Zeichnen auf der Bitmap wäre LockBits und UnlockBits, um direkt auf die Pixeldaten der Bitmap zugreifen zu können.