2009-06-12 4 views
4

Lorsque je crée un éditeur de mappage en C#, j'ai tendance à parcourir les axes X et Y et à appeler Graphics.DrawImage() pour mettre en place une seule mosaïque, à partir d'un bitmap sur une carte Bitmap. Ce processus prend plusieurs secondes à compléter, donc je ne le fais qu'une seule fois lors du chargement d'une nouvelle carte ou de la modification de son ensemble de pièces. Toutes les modifications à partir de là sont des blits relativement rapides de seulement la tuile éditée. Maintenant, je me suis assis plus tôt aujourd'hui et j'ai réfléchi à mes options. Graphics.DrawImage() est le seul des trois (les autres étant DrawImageUnscaled et DrawImageUnscaledAndCropped (?)) Qui permet la spécification d'une origine source. DrawImageUnscaled() était beaucoup, beaucoup plus vite, mais toujours blitted à partir du coin supérieur gauche de la bitmap source.Est-ce que ce blitter de tuiles pourrait devenir plus rapide?

En contraste frappant avec les vitesses de QuickBasic PSET par rapport POKEing la mémoire vidéo ou PSet de VB6 par rapport à setPixel de WinAPI, simple boucle Get/de SetPixel était aussi rapide qu'un appel DrawImageUnscaled, mais a fait la culture qui ne DrawImage serait sinon fais.

C'est assez rapide pour l'instant, mais je me demandais comment quelque chose comme la manipulation d'image directe pourrait l'accélérer encore plus? Quelque chose avec LockBits peut-être, une fonction que je connais à peu près rien?

+1

Ce n'est pas vraiment la réponse à votre question, mais vous pouvez augmenter la vitesse de la DrawImage en définissant le rectangle entier de l'image -> X, Y, Largeur, Hauteur. Dans mon test, j'ai réalisé environ 20% d'accélération. –

Répondre

1

Il y a une excellente réponse pour cela à .. How to manipulate images at the pixel level in C#

Si vous allez la route LockBits pourriez-vous poster un suivi avec les différences de vitesse.

+0

Je vais regarder là maintenant, et voir ce que je peux trouver. Merci. – Kawa

1

Le blocage de logiciel semble être un goulot d'étranglement grave. Je suggère sérieusement de regarder dans le dessin accéléré de matériel pour une tâche comme ceci.

+0

Au moins, le cou est notablement plus large. – Kawa

1

simple boucle get/SetPixel était aussi rapide comme un appel DrawImageUnscaled

Ensuite, vous faites certainement quelque chose de mal. Les méthodes GetPixel et SetPixel ont beaucoup de frais généraux, en utilisant l'une des méthodes DrawImage devrait être quelque chose comme 100 fois plus rapide (sauf peut-être si vos tuiles sont très petites, comme 2x2 pixels).

Contrairement à son nom, la méthode DrawImageUnscaled ne dessine pas sans redimensionnement. Au lieu de cela, il utilise les paramètres PPI des images pour les mettre à l'échelle aux mêmes mesures. Cela signifie que si vous avez un bitmap avec le paramètre 100 PPI, et dessinez dessus un bitmap avec le paramètre 50 PPI, il sera redimensionné à la taille double.

Si vous dessinez les images à une taille inchangée, vous pouvez modifier les paramètres de qualité dans l'objet Graphics pour modifier la vitesse. Vous pouvez par exemple définir la propriété InterpolationMode sur NearestNeighbor pour l'empêcher d'effectuer une interpolation. Une alternative au dessin sur le bitmap serait d'utiliser LockBits et UnlockBits pour accéder directement aux données de pixel du bitmap.

Questions connexes