Aussi pratique que canvas.pixels[ ] mais jusqu'à 450 fois plus rapide (grâce à scanline)

Soyez le premier à donner votre avis sur cette source.

Vue 7 649 fois - Téléchargée 793 fois

Description

Pour balayer un Bitmap, nous utilisons Scanline qui est la méthode la plus rapide.
Cependant, lorsque nous avons besoin de connaître et/ou de changer les composantes RGB d'un Pixel précis (typiquement dessiner une courbe point par point), nous utilisons souvent 'Bitmap.Canvas.Pixels[X,Y]' qui est bien pratique malgré sa lenteur. C'est facile et ça marche sur tous les formats de Pixel et sur toutes les largeurs de Bitmap.

Ce que je vous propose aujourd'hui, c'est une méthode qui allie la facilité d'utilisation de 'Bitmap.Canvas.Pixels[X,Y]' à la rapidité de ScanLine : GetpPix().

LE BUT était de trouver un algorithme, le plus rapide possible, permettant d'atteindre un pixel donné afin de pouvoir consulter et modifier sa couleur. Ceci devant être possible sur un PixelFormat de pf24bit ou de pf32bit (les plus courants).
Pour la performance, le travail devait se faire en mémoire, mais la largeur du Bitmap (surtout pour pf24bit) ne devait pas poser de problèmes.
Il s'agissait donc de faire correspondre des coordonnées (X,Y) du bitmap avec un pointeur précis de la zone mémoire où est stocké le Bitmap.

LES DIFFICULTES étaient liées à la dispositions des pixels en mémoire. En effet, la mémoire Windows est une sorte de trame basée sur 4 octets.
Les Bitmaps sont stockés ligne par ligne et il peut arriver que la fin d'une ligne de pixels ne coïncide pas avec la trame de la mémoire. La conséquence est qu'on peut trouver des pointeurs inutiles en fin de ligne, qui rompent la belle progression arithmétique de ScanLine. De plus, les lignes du Bitmap peuvent être stockées de deux manières : de bas en haut ou de haut en bas.
Pour vous faire une idée plus visuelle de la façon dont sont stockés les pixels en mémoire, je vous conseille vivement de consulter cette page :

http://msdn.microsoft.com/en-us/library/dd407212(VS.85).aspx

Je ne parlerai pas des RGB, BGR, BGRA et ARGB, sans doute aussi inventés par le même agité du bocal qui a commis la structure Bitmap et qu'il trouvait sans doute encore trop simple... lol

LES SOLUTIONS existent. Il s'agit de déterminer la longueur d'une ligne en mémoire afin de pouvoir calculer arithmétiquement le pointeur correspondant à la ligne Y, en incrémentant le pointeur donné par ScanLine. Ensuite, il suffit de l'incrémenter de X fois la taille d'un pixel pour trouver l'adresse du pointeur correspondant à (X,Y).
Les deux tailles possibles d'un pixel (3 ou 4 bytes), ainsi que l'ordre de stockage des bytes RGBA seront facilement résolus en n'utilisant qu'un pRGBTriple, pointeur qui ne renvoie que les trois couleurs de base sous forme de 3 bytes (NB: GetpPix ne nécessite donc pas de transtypage pour travailler sur les valeurs RGB).
Il existe plusieurs façons d'obtenir le taille d'une ligne mémoire, mais la plus élégante (celle de Danny Thorpe, ingénieur Borland) est de simplement calculer Scanline[1] - Scanline[0] (en Integer, bien sûr). En effet, la valeur absolue nous donnera la taille d'une ligne mémoire (en bytes), mais de plus le signe nous permettra de travailler indifféremment sur un Top-Down ou un Bottom-Up DIB.

Je pense que les débutants en savent maintenant assez pour comprendre ce code qui ne présente aucune difficulté (bien que les pointeurs c'est... pointu).

Conclusion :


NB1 : En plus de Canvas.Pixels[], j'ai comparé GetpPix() aux méthodes suivantes avec toujours de bien meilleurs résultats pour mon algo :
- Windows.SetPixel
- Windows.SetPixelV
- Windows.GetDIBits & Windows.SetDIBits

NB2 : La méthode peut être adaptée à tous les autres PixelFormat.

NB3 : Contrairemant à Canvas.Pixels[], GetpPix() plante quand (X,Y) se trouve en dehors de la surface du Bitmap. C'est voulu. Je trouve qu'il est plus logique d'éventuellement vérifier cette condition avant l'appel de la fonction dans le cas où cela pourrait se produire (ce qui est loin d'être toujours le cas).

A ma connaissance, cet algo n'a jamais été publié (ce qui m'étonne un peu, mais bon !.. Je me trompe peut-être).

Je remercie Cashemire pour sa gracieuse prestation (J'ai pas pris le chat de Bacterius car il est déjà en niveaux de gris). :)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
234
Date d'inscription
mardi 13 novembre 2007
Statut
Membre
Dernière intervention
21 novembre 2013

L'histoire du TThread : c'est une idée pour ceux qui aiment l'animation graphique...puisque cela mets le même temps d'éxécution....

Quand à pourquoi des sources, des sources et d'autres sources ?

1) mieux vaut des bombes que des sources ?
2) on apprends tous les jours que le Seigneur fait
3) la gestion (le pascal) à beaucoup à apprendre de Windows (les messages/Delphi) !

:)
Messages postés
7
Date d'inscription
jeudi 29 octobre 2009
Statut
Membre
Dernière intervention
23 novembre 2010

Finalement je doit être comme tu la mentionné un peut borderline.
Mais fait gaffe à l'adiction :) c'est un des symptomes.
Je me suis emporté je pense après coups.
Je vous respectes plus loin que mes paroles.
Mais dès fois fo remuer le truc pour savoir.

A Bientôt.
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
13
Moi, je vais développer.

je suis revenu à la programmation sur le tard, avec Java, en tant qu'opticien.
J'ai tout de suite participé à un projet énorme ( http://antares.in2p3.fr/Apercu/index_fr.html ). Les universitaires ne jurent que par Java (j'ai pas encore compris pourquoi).

Malgré cela, je n'ai jamais trouvé une communauté de programmeurs plus "partageuse" et "efficace" que celle du Pascal et de Delphi. J'ai tout de suite abandonné Java pour Delphi, et j'ai tout appris sur ce site.

Maintenant que j'en sais un peu plus, j'essaie de partager. D'autres l'ont fait avant moi, delphiprog, nono40, etc...

Avec Cirec, Bacterius, et bien d'autres on fait de notre mieux et je trouve injuste de dire qu'on enterre Delphi.

Pour moi, Delphi est actuellement victime de son efficacité et de sa simplicité pour développer des BDD par des pollueurs sauvages qui n'ont aucune notion de la logique.

J'espère simplement que ce ne seront pas eux qui feront oublier les vertus du Pascal et la fraternité de notre communauté.
Messages postés
7
Date d'inscription
jeudi 29 octobre 2009
Statut
Membre
Dernière intervention
23 novembre 2010

@Caribensila :01:38:54
Oki, mais il existe aussi les Anti-borderline.
Faute de piles dans mon key sans fil (et c'est vrai). Je n'ai pas eu la possibilité de dire que :
Mr Caribensila and Mr cirec OKI vous êtes pas mes cibles.

Mon débat etait plus sur... Oki les sources , mais pour qui et pour quoi ?
Le débat sur la source... Pour qui et pour quoi ?
Je pense que vous vous mettez sous terre, que vous mettez le pascal sous terre, voila.
C'est ma pensée, je ne dit pas que cela est la véritée.
Mais je constaste :
1 - Pascal ou Delphi. Bof pas de fréquentation.
2 - Les gars qui viennent, ben c'est juste du tech, du DUT d'la recherche.
3 - Le pascal ben on a l'impression que c'est un langage juste de test.
.....

je vais pas développer.

Amicalement
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
13
Pour ce qui concerne mes motivations (bien que ça ne regarde que moi, et certainement pas le dernier excité venu), je précise que ce source sert à compléter ce tuto qui, perso, me semble très didactique mais cependant incomplet :

http://nono40.developpez.com/tutoriel/delphi/efg/scanline/#LV-A
Afficher les 43 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.