Performances : trouver où ça freine

Résolu
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 - 11 juil. 2019 à 11:58
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 - 19 juil. 2019 à 17:53
Bonjour,
Je constate qu'un de mes programmes en VB6 est particulièrement lent.
J'ai bien essayé de mettre des GetTickCount() mais le programme est un peu complexe avec des boucles Do/Loop et des For/next imbriqués ainsi que l'appel à de nombreuses sub : difficile d'exploiter les résultats.
Existerait-il un outil ou une méthode permettant de tracer l'exécution pour voir où il passe le plus de temps ?
Merci d'avance pour vos réponses

9 réponses

Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
Modifié le 14 juil. 2019 à 12:08
J'ai trouvé un autre moyen que PtInRegion pour savoir si un point se trouve dans un polygone :
on calcule la somme des angles entre le point en question et chaque sommet
si le point se trouve dans le polygone la somme = ±Pi sinon elle est nulle

je ne gagne cependant pratiquement rien :
pour le calcul complet avec PtInRegion = 21891 ms, avec le calcul de l'angle = 21516 ms.

Que veux-tu dire par "arithmétique des pointeurs" et "Le calcul de factoriel" ?

Comment pourrai-je faire 3 tableaux ?
J'utilise la fonction GDI GetBitmapBits pour le remplir; il faudrait que je le copie dans 3 tableaux à 2 dimensions pour le traiter puis le recopier dans un tableau à 3 dimensions pour que la fonction GDI SetBitmapBits le retransforme en image.
1
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
14 juil. 2019 à 15:11
Merci, pour cette nouvelle méthode de détermination d'un point à l'intérieur d'un polygone, je ne l'a connaissait pas celle la ! d'ou nous tire-tu cela ? d'autre part il te reste peut-être à essayer un traitement multi-threader, avec tes deux boucles for x et for y si tu as bien un microprocesseur multi-coeur, tu peut essayer, mais je ne pourrais pas te dire comment faire en Basic, parce que ce n'est pas le langage que j'utilise, il te suffirait de créer 4 threads (par exemple) avec une fraction pour chaque boucle for x qui bien sûr encapsulerais aussi la boucle for y. (suggestion).
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
14 juil. 2019 à 15:27
Un tableau en mémoire vive est déterminer par une adresse en mémoire dans le langage pascal - delphi tu peut obtenir p=@tableau (p l'adresse du tableau en mémoire mais je ne sais pas ssi on peut le faire en basic, pour accéder à l'élément suivant plutôt que de tout recalculer, il suffit d'incrémenter P de la taille (sizeof) de l'élément.

https://fr.wikipedia.org/wiki/Pointeur_(programmation)#Arithm%C3%A9tique_des_pointeurs
0
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
15 juil. 2019 à 14:32
Bonjour,
J'ai essayé une autre méthode que PtInRegion pour savoir si un point se trouve dans le polygone en comptant le nombre d'intersections d'un segment partant du point vers la droite avec les côtés : je ne gagne rien.
Il semble donc que la perte de temps se trouve bien dans l'accès de l'array mais je ne vois vraiment pas comment la diminuer.
1
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
Modifié le 15 juil. 2019 à 15:27
Comme tu as du te rendre compte en supprimant le test de détection pour savoir si un point est bien à l'intérieur de ton polygone, le temps d'exécution était véritablement
beaucoup plus rapide, donc le temps perdu est bien dans cette fonction !
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7
Modifié le 15 juil. 2019 à 18:48
Salut Hervé,
Pour réduire la taille de l'image, tu dois utiliser un autre format BM (1bit, 8bits ou 32bits).
Je ne voie pas de solutions simple, à part passer le RVBc 32bits en tableau 256 couleurs…
Le mieux est de la convertir en niveau de gris, et de traiter un masque en gris sur la transparence de chaque couches ou sur l'ensemble des couches avec le même masque.
Le calcul des masques sera plus rapide, et l'application des masques peuvent se faire en GDI, tout aussi rapidement.
Mais, avec les tests que j'ai fait, le gain n'est pas important sur les trois couches, donc on risque de perdre le temps gagné en recalculs, pré-traitement et post-traitement. Donc, j'y crois pas trop.

@denisbertin : Si c'est une fonction de traitement d'objet, la recoder ne servira à rien!
Il vaut mieux compiler le programmes sans "tester les variables" et utiliser options "brute" d'optimisation d'accès aux variables.

Nota:^pour Hervé : retire les "Debug.print" en mode "débogage", ça vas plus vite !
;)
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
16 juil. 2019 à 03:11
Si tu veux vraiment savoir si un pixel est situé dans un polygone de façon très très rapide, créer un bitmap de la taille (surface) de ton polygone, ce bitmap doit avoir un fond blanc (par exemple) dessine ton polygone avec une couleur bleu (différente du blanc), parcours dans deux boucles X et Y ce bitmap à chaque fois que ce pixel est bleu tu es à l'intérieur du polygone ! la méthode la plus rapide.... ton bitmap peut être monochrome (seulement noir ou blanc) pour être encore plus efficace.
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7
11 juil. 2019 à 12:31
Salut Hervé,

La programmation sur le vb5 ou 6 est une philosophie…
Tu peux gagner du temps d'execution sur les options de compilation, en retirant toutes les vérifications de variables…

Mais, un bon code est un code optimisé.
Oublie les fonctions chronophages du basic, et pense C# !
N'utilise plus de chaînes, mais des tableaux en BYTES…

Déclare chaque valeur en LOCAL et réduis les longueurs de chaînes.
Quite a effacer les données traitées.

Il y a plein d'astuces pour "booster" les traitements… mais, la plupart du temps, c'est un problème lié à la lourdeur de la gestion des variables.

Et à force de répétitions, ces latences systèmes te font perdre un temps énorme en fin de boucle.

Donc, STRING en BYTES() puis BYTES() en STRING.
Travail sur des variables de taille réduite en string, ou sur une copie qui sera tronquée.

Utilisation des API comme Copymemory sur les bytes et STRING.
Le temps gagné est non négligeable.
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7
Modifié le 11 juil. 2019 à 12:40
Ha, oui !
évite les sub/fonctions trop nombreuses dans les boucles si elle ne sont pas justifiées.
Mieux vaut réécrire un petit morceau de code, que de forcer le code à jumper sur une routine en PUBLIC qui aura à transférer les infos à chaque fois.
Limite le nombre de ligne et utilise IIF(x,x,x) au lieu des IFs…
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7
Modifié le 12 juil. 2019 à 01:13
Le secret est de limiter le nombre de lignes, et de tests inutiles…

IF a$="a" then …
IF a$="b" then …


Est a proscrire.
Utiliser:

DIM a as string*1

Select Case cbyte(a)

Case &H0
StrText = "NOP"


Ne pas hésiter à faire des tests élargis avec des GOTOs pour éviter les tests inutiles et chronophages. Pareil pour les SUB et les fonctions (sortie avec des Exit Sub ou Exit Function) avant la fin de la sub ou de la fonction.
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
12 juil. 2019 à 11:56
Monsieur Niklaus Wirth qui a élaboré le langage de programmation Pascal pensé dans son langage de prédilection que tous les Goto pouvais être éliminé, ce n'était pas le cas, car même quand dans un test if then else ce compilateur produisait des jump to une adresse en assembleur une fois compilé, cependant sa formulation exact était correct, dans mon programme logiciel écrit dans ce langage je me suis bien sur amuser à exclure tous les sots en mémoire comme ont pourrais le faire avec un @label. et de vérifier ces propositions. Bien sûr les nombreuses répétitions du même test comme dans l'exemple "Une couleur au hasard avec choix de la couleur et du ton" peuvent être évitée car elle forme des redondances inutile.

https://fr.wikipedia.org/wiki/Niklaus_Wirth
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
11 juil. 2019 à 21:32
La fonction GetTickCount() permet d'obtenir le temps en milliseconde de la valeur de ce compteur de temps et ne permet pas d’optimiser ton programme mais de mesurer sa période en milliseconde, tu va alors recevoir une valeur que tu peut comparer avec le GetTickCount() en sortie de ton module, avec la différence entre ces deux valeurs qui permet d'obtenir le temps de latence ou d’exécution de ce module time actuel - time_before; en milliseconde, Si tu veux aussi comprendre la somme des instructions d'un module est égal à la somme des instructions qui le compose. si tu effectue des boucles for i = n to m, toutes les variables qui ne sont pas une fonction de i peuvent être écrite en aval de cette boucle et prédéterminées à l'avance, la fonction call to subroutine empile dans le stack segment (le segment de pile) tous les paramètres de cette fonction soit n paramètre(n) et une fonction, si tu veux éviter cette accumulation ton code deviendras plus illisible mais peut-être qu'il fonctionneras un peut plus rapidement du fait de la linéarisation de ton code sans différer, en définitive tous le monde devrait commencer par apprendre le langage assembleur des microprocesseurs pour savoir ce qu'il font vraiment, denis.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
Modifié le 13 juil. 2019 à 11:49
Bonjour et merci pour vos réponses (je n'ai pas reçu de notification).
J'ai trouvé un outil d'analyse : VB Watch.
L'essentiel du temps est passé dans une boucle (2 for/next imbriqués) qui sert à modifier une image bitmap : je copie l'image dans un array et j'y dessine un polygone transparent,
Opacité est celle du polygone à dessiner, transparence celle de ce qu'il y a en dessous
CC1, 2 et 3 sont les 3 couleurs RGB du polygone à dessiner
voici le code
Dim rgn  As Long  '  région
Dim Xleft As Integer
Dim Xright As Integer
Dim X As Integer
Dim Y As Integer
Dim Ybottom As Integer
Dim Transparence As Single
Dim Opacite As Single
Dim fx As Single
Dim fy As Single

rgn = CreatePolygonRgn(Vertices(0), Vertex, Winding)
Call GetObject(Graph(n).Image, Len(PicInfo), PicInfo)
ReDim ImageArray(3, (PicInfo.bmWidth - 1), (PicInfo.bmHeight - 1)) As Byte
Noctets = PicInfo.bmWidth * PicInfo.bmHeight * 4
Call GetBitmapBits(Graph(n).Image, Noctets, ImageArray(0, 0, 0)) ' Copie image dans array
For X = Xleft To Xright        ' Abscisses min et max du polygone à dessiner
        For Y = Y1 To Ybottom        ' Ordonnées min et max du polygone à dessiner
                If PtInRegion(rgn, X, Y) <> 0 Then
                        Transparence = 1 - Opacite       
                         ImageArray(0, X, Y) = (ImageArray(0, X, Y) * Transparence) + (CC3 * Opacite)
                         ImageArray(1, X, Y) = (ImageArray(1, X, Y) * Transparence) + (CC2 * Opacite)
                         ImageArray(2, X, Y) = (ImageArray(2, X, Y) * Transparence) + (CC1 * Opacite)
                 End If
         Next Y
Next X
Call SetBitmapBits(Graph(n).Image, Noctets, ImageArray(0, 0, 0)) ' Copie array dans image
Call DeleteObject(rgn)
Ce qui prend le plus de temps est (3 fois)
ImageArray(0, X, Y) = (ImageArray(0, X, Y) * Transparence) + (CC3 * Opacite)
comment pensez-vous que je pourrais accélérer ?
0
pascal16m Messages postés 73 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 12 novembre 2020
13 juil. 2019 à 15:39
faire ImageArray(0, X, Y) puis ImageArray(1, X, Y) provoque un grand saut en mémoire qui est recalculé à chaque fois donc lent en accès.

essaies de séparer en 3 boucles
une boucle qu'avec des ImageArray(0, X, Y)
une boucle qu'avec des ImageArray(1 X, Y)
une boucle qu'avec des ImageArray(2, X, Y)
Y étant la dernière dimension du tableau, X et Y sont appelés dans le bon ordre

CCx * Opacite est-il constant ? si oui, sort-le de la boucle et crées une variable qui contient cette valeur une fois pour toute.

ensuite tu ré-affectes la valeur au même tableau, vu qu'on ne peux pas lire et écrire une valeur en même temps, il y a des latences rajoutée (les optimisations qui permettent de faire plusieurs opérations en 1 cycle d'horloge ne se font pas). Tu peux envoyer tes valeurs dans un second tableau, ça perd de la ram, mais ça a de grandes chances d'aller plus vite.

si tu peux faire du multi thread (je sais pas en vb6). tu peux extraire 3 sous tableaux 0, 1 et 2, et tu lances 3 calculs en parallèle, que tu assembles ensuite.
Comme les appels sont indépendants, tu n'auras pas de blocage ou ralentissement inter thread
0
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
13 juil. 2019 à 16:12
Merci pour ta réponse,
Le polygone représente un faisceau lumineux de moins en moins intense au fur et à mesure qu'on s'éloigne de la source; par conséquent "Opacite" n'est pas constant, il est recalculé pour chaque combinaison X,Y.
Par conséquent si je fais 3 boucles ImageArray(0/1/2 je gagnerai en accès au tableau mais je devrai recalculer Opacite 3 fois plus souvent, pas sur au final que j'y gagne qqch.

Par contre lire un array et écrire dans un autre c'est facile, j'ai de suite essayé.
Bizarrement je ne gagne rien : une boucle dure toujours 235 ms !
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
13 juil. 2019 à 17:50
C'est certainement la fonction PtInRegion qui est trop lente.
0
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
13 juil. 2019 à 18:00
J'ai essayé avec une opacité fixe de faire 3 boucles : surprise, c'est encore plus lent.
La raison est en effet que je dois appeler PtInRegion 3 fois plus souvent.
J'ai supprimé cet appel; évidemment ça ne fonctionne plus parce qu'il altère tous les pixels et pas uniquement ceux situés dans la région mais c'est beaucoup plus rapide.

N'y a-t-il pas moyen de trouver une fonction plus performante pour vérifier si un pixel est bien dans le polygone ?
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
13 juil. 2019 à 18:35
Je ne sais pas si vraiment la fonction ptinrgn, est multi-threadable, la majorités des fonctions du GDI ne le sont pas, elles ne sont pas ré-entrante et se croisent toutes et ne fonctionne pas en multi-coeur. Pour ma part j'ai écrit beaucoup de fonctions multi-threadé pour cela je créer autant de thread qu'il y a de coeur de calcul, si la boucle : for i=1 to 100 je donne quatre fraction de 100 à chaque coeur, soit une boucle de 1 à 25, pour le premier coeur, de 26 à 50 pour le deuxième coeur et ainsi de suite... mais il faut utiliser des fonctions réentrantes, initialiser un sémaphore pour synchroniser les taches. et réécrire ptinrgn, pour cela si tu prend un point donné, tu lance un rayon dans n'importe quel direction, (la vertical) si le nombre d'intersection de ce rayon avec les segments de ton polygone est impair, ce point est à l'intérieur du polygone.
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
Modifié le 13 juil. 2019 à 19:12
Pour cela dessiner un polygone quelconque (concave ou convexe) sur une feuille de papier, se munir d'un stylo à bille bleu (la couleur est indifférente), placer son doigt au sommet de ce stylo, puis lui donner un mouvement longitudinale, compter le nombre d'intersection ?
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
13 juil. 2019 à 19:42
Si tu veux comprendre un traitement multi-threader pour le répartir sur de nombreux cœur de calcul, dans mon langage de prédilection comme je l'ai formulé tu peut observer ce code source, que j'ai publié à l'intention des internautes et des membres de code source, comment ça marche :

https://codes-sources.commentcamarche.net/source/55268-caculer-une-factorielle-avec-plusieurs-coeur-de-calcul-et-afficher-les-temps-d-executions
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
13 juil. 2019 à 20:52
Si tu veux connaître une autre optimisation possible quand tu accède à un tableau à trois dimensions, soit P l'adresse de départ de ton tableau en mémoire, alors si ce tableau est composé de N dimensions, alors l'adresse de P(x,y) est égal à P + X + Y multiplier par la largeur du tableau en deux dimensions quand tu adresse un élément de ce tableau pour multiplier sa valeur par un coefficient de transparence dans ton calcul tu effectue deux fois cette opération pour adresser l'élément p(i,j) or une seule adresse en mémoire correspond à ce calcul, mais tu effectue sur trois dimensions ces même opération : ImageArray(0, X, Y) = (ImageArray(0, X, Y) * Transparence) + (CC3 * Opacite), tu peut te rendre compte que l'adresse en mémoire de ImageArray(0, X, Y) est égale mais tu effectue deux fois ce calcul, l'arithmétique des pointeurs te permettrais de la faire une seule fois.
0
denisbertin Messages postés 245 Date d'inscription lundi 22 avril 2013 Statut Membre Dernière intervention 13 mai 2023 1
Modifié le 13 juil. 2019 à 22:13
Le calcul de factoriel en trois caractères a=1; for i =1 to n do a=a*i; result a;
0
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
Modifié le 14 juil. 2019 à 18:16
@denisbertin Que veux-tu dire par "arithmétique des pointeurs" et "Le calcul de factoriel" ?

@jeudutaquin Comment pourrai-je faire 3 tableaux ?
J'utilise la fonction GDI GetBitmapBits pour le remplir; il faudrait que je le copie dans 3 tableaux à 2 dimensions pour le traiter puis le recopier dans un tableau à 3 dimensions pour que la fonction GDI SetBitmapBits le retransforme en image.
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7
Modifié le 15 juil. 2019 à 01:46
Salut,

Tu dois imaginer le traitement des variables en VB6 comme un process linéaire à accès séquentiel.
En gros, la valeur x,y est recherchée pas sauts de valeurs.
Donc, plus le tableau est grand, plus il mettra de temps à traiter l'accès aux informations.

Tu dois dans le cas d'un fichier ou variable de grande taille, le 'streamer' par fragmentations pour en réduire la taille.
Le temps d'accès s'en trouve réduit pour l'ensemble du traitement.
Tu prends ton tableau en 3 niveaux, et tu le sépare en 3 tableau de 2 dimensions.

DATA (Niveau 0:Data (x,y),Niveau 1:Data (x,y),Niveau 2:Data (x,y))

DATA Niveau 0: Data (x,y)
DATA Niveau 1: Data (x,y)
DATA Niveau 2: Data (x,y)

Pour cela, il te faut utiliser la fonction COPYMEMORY (en Bytes<>Bytes) et le pointeur mémoire VarPtr()
Dans le cas d'une variables à plusieurs niveaux, il faut connaitre la structure d'encombrement mémoire de cette variable!
Généralement stockée par bloc, il te faut copier ces blocs de manière précautionneuse, car le COPYMEMORY peut créer des débordements et des effacements de d'informations les variables stockées en mémoire.
Mais, si le COPYMEMORY est bien cadré, le process est sûre et rapide.

Il faut faire des tests pour voir si il est possible d’établir une réversibilité vers la variable en 3 dimension avec la même technique.

Et je pense que @denisbertin te suggère de linéariser ton tableau 2 dimensions en en tableau simple où ton point se trouve en (y*width)+x, ce qui doit aussi éviter des cycles de scrutation mémoire.
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7
Modifié le 15 juil. 2019 à 08:01
Salut,
Après avoir testé un code de dissection d'une variable de 3 vers 2 dimensions…
Le traitement est plus rapide… mais corrompu.
Sub Test3()
Dim x, y As Integer
Dim Image0(3000, 3000) As Byte
Dim Image1(3000, 3000) As Byte
Dim Image2(3000, 3000) As Byte

CopyMemoryByte Image0(0, 0), Image3D(0, 0, 0), 3000 + 1
CopyMemoryByte Image1(0, 0), Image3D(1, 0, 0), 3000 + 1
CopyMemoryByte Image2(0, 0), Image3D(2, 0, 0), 3000 + 1

For x = 0 To 3000
For y = 0 To 3000
Image0(x, y) = (x + y) And 255
Image1(x, y) = (x + y) And 255
Image2(x, y) = (x + y) And 255
Next y, x

CopyMemoryByte Image3D(0, 0, 0), Image0(0, 0), 3000 + 1
CopyMemoryByte Image3D(1, 0, 0), Image1(0, 0), 3000 + 1
CopyMemoryByte Image3D(2, 0, 0), Image2(0, 0), 3000 + 1

End Sub

Car les niveaux sont indexés ainsi:
DIM a(x)= 1234567
DIM a(x,y)=11223344556677
DIM a(x,y,z)=111222333444555666777
Et copymemory est bêtement linéaire… donc, il efface tout.
La seule solution est de créer un fichier temporaire et d'y PUT#er les valeurs les unes après les autres et de faire un GET# de la variables en 3 niveaux.
Ce qui est beaucoup plus long.
On peut tout mettre dans un tableau simple de longueur 3 fois plus grande en X,X+1 et X+2... mais, on ne gagne plus rien en rapidité… et c'est même pire.
Par contre, pour annoncer une bonne nouvelle (au moins une), ton choix de For-next est le bon… DO-loop est plus lent de pas grand chose, mais bon…

Pour les réponses de @denisbertin, je suis un peu perdu!
Il faut garder en mémoire que nous somme sur du VB6, programmé pour le Windows 95 … multi-tâches en win32... mais que la notion de "simultanéité", "multi-cores" et "multi-procès" … étaient de la science fiction à celle époque. Même si les DLLs et les routines sont supportées, il faut rester humble face aux possibilités d'un logiciel qui a survécu au bug de l'an 2000. Oui, une DLL en assembleur serai la solution, mais autant changer de language dans ce cas.

Donc, l'accélération ne peut être que dans la forme et non le fond.
0
JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023 7 > JeuDuTaquin Messages postés 249 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 31 mai 2023
15 juil. 2019 à 10:17
Pas de gain en rapidité… tableau trop grand.
Private Declare Sub CopyMemoryByte Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Dim Image3D(2, 3000, 3000) As Byte
'-------------------------------------

Erase Image3D
Dim Image4((3001 ^ 2 * 3) - 1) As Byte ' image(2,3000,3000)=>3*3000*3000=3000^2*3
For x = 0 To ((3001 ^ 2 * 3) - 1) Step 3
Image4(x) = (x) And 255 ' tableau 1: image(0,x,x)
Image4(x + 1) = (x) And 255 ' tableau 2: image(1,x,x)
Image4(x + 2) = (x) And 255 ' tableau 3: image(2,x,x)
Next x

CopyMemoryByte Image3D(0, 0, 0), Image4(0), (3001 ^ 2 * 3) + 1

0
Herve_be Messages postés 1015 Date d'inscription mercredi 4 août 2010 Statut Membre Dernière intervention 10 mars 2024 2
19 juil. 2019 à 17:53
J'ai finalement trouvé une solution très rapide : Alphablend.
Je mélange l'image ci-dessous avec l'image déjà créée en délimitant le contour avec un array de sommets.
Merci pour votre aide, problème résolu

0
Rejoignez-nous