Page 2 sur 3

Publié : lun. 02/juin/2008 19:28
par djes
Tu devrais mieux étudier la structure bitmap; tu ne prends pas en compte ses spécificités.

Publié : lun. 02/juin/2008 19:32
par Octavius
Ah ? :(

Et qu'ai-je oublié comme paramètre ? :oops:

Publié : lun. 02/juin/2008 20:16
par Octavius
Je me suis tapé de la doc sur les bitmaps, j'ai trouvé un truc intéressant :
Chaque ligne de l'image doit comporter un nombre total d'octets qui soit un multiple de 4; si ce n'est pas le cas, la ligne doit être complétée par des 0 de telle manière à respecter ce critère.
Alors du coup, évidemment que ça marche toujours avec 32 bits, puisque ça fait exactement 4 octets par pixel. Avec 24 bits (3 octets), selon le nombre de pixels, il faut compléter la taille de la ligne pour que ce soit un multiple de 4.

Suis-je sur la bonne voie djes ? (tu sembles en savoir plus que moi sur les bitmaps djes :? )

Du coup j'ai fait une tentative de code qui prend en compte ces zéros supplémentaires de fin de ligne... Et ça échoue lamentablement. Voici mon code :

Code : Tout sélectionner

Procedure.l ReverseRGB(Color.l)
  ProcedureReturn RGB(Blue(Color),Green(Color),Red(Color))
EndProcedure

Procedure.l PointMemory(Image.l,X.l,Y.l)
  Protected bmp.BITMAP,Color.l,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ProcedureReturn -1
  EndIf
  
  ;Décalage, bits nuls à droite
  Offset=Width*Depth-Width*Depth/4*4
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp) : *Address=bmp\bmBits
  
  ;Récupération de la couleur du point
  If *Address
    CopyMemory(*Address+X*Depth+Y*Depth*(Width+Offset),@Color,Depth)
  EndIf
  
  ;Attention à bien inverser les conventions BGR et RGB
  ProcedureReturn ReverseRGB(Color)
  
EndProcedure

Procedure.b PlotMemory(Image.l,X.l,Y.l,Color.l)
  Protected bmp.BITMAP,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ;Echec de l'opération
    ProcedureReturn #False
  EndIf
  
  ;Décalage, bits nuls à droite
  Offset=Width*Depth-Width*Depth/4*4
  
  Debug Offset
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp) : *Address=bmp\bmBits
  ;Inversion de la convention RGB et BGR
  Color=ReverseRGB(Color)
  ;Collage du point dans l'image
  If *Address
    CopyMemory(@Color,*Address+X*Depth+Y*Depth*(Width+Offset),Depth)
  EndIf
  ;Réussite de l'opération
  ProcedureReturn #True
  
EndProcedure

CreateImage(0,295,189,24)
CreateImage(1,295,189,24)
ResizeImage(1,590,398,#PB_Image_Raw)

PlotMemory(0,10,10,$FFFFFF)
PlotMemory(1,10,10,$FFFFFF)

SaveImage(0,"image1.bmp")
SaveImage(1,"image2.bmp")
En gros j'ai remplacé l'ancienne formule de l'adresse du pixel :

Code : Tout sélectionner

*Address+X*Depth+Y*Depth*Width
Par celle-là :

Code : Tout sélectionner

*Address+X*Depth+Y*Depth*(Width+Offset)
L'Offset est calculé de cette manière :

Code : Tout sélectionner

Offset=Width*Depth-Width*Depth/4*4
J'ai toujours deux points de couleur bleu et jaune sur la grande image. En 32 bits par contre ça marche bien.

Publié : lun. 02/juin/2008 20:27
par Backup
si tu cherche a remplacer point et Plot
ça a deja ete fait :)

de Clp.Bator :)

Code REEDITE !!!

Code : Tout sélectionner


 ; le CERCLE
 ; exemple de cercle
; bouge = bouge + 1
; PSet (6000 * Cos(bouge) + (Screen.Width / 2), 6000 * Sin(bouge) + (Screen.Height / 2)) 
; angle en degré = 180 * (angle en radian) / pi 
;         ;Plot(WindowMouseX(), WindowMouseY(), RGB(255,255,255))  
;         ;sin*compt*phase/nmbr de point *amplitude 
;Plot (60 * Cos(bouge) + (512 / 2), 60 * Sin(bouge) + (512 / 2),RGB(2,0,255))
Declare rapide_Point(x,y)   
Declare rapide_Plot(x,y,color) 

#dobro=1
#Police=1
#Sprite=1
; ***********************************
Resultat = InitSprite()
FontID = LoadFont(#Police, "arial", 50, #PB_Font_Bold )
EcranX = GetSystemMetrics_(#SM_CXSCREEN):;=largeur de l'ecran
EcranY = GetSystemMetrics_(#SM_CYSCREEN):;=hauteur de l'ecran
    WindowID = OpenWindow(1, 0, 0, EcranX, EcranY, "hello", #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered ) 
    
    WindowID = WindowID(1) 
    Result = OpenWindowedScreen(WindowID,0,0, EcranX, EcranY, 1, 0,0)  
    Resultat = InitMouse() 
    Repeat
        ExamineMouse() 
        Event=WaitWindowEvent() 
        StartDrawing( ScreenOutput())   
            compt+1  
            y= Sin(180*(compt*1/10000)/#PI) * (768 / 4) +768 / 2
            x= Cos(180*(compt*1/10000)/#PI) * (1024 / 4)+1024 / 2 
            
            rapide_Plot(x,Y,RGB(0,255,0))  ; Procedure de Remplacement
            
            ;Plot(x, y,RGB(255,255,255))   ; plot ordinaire :o)
            
        StopDrawing() 
        FlipBuffers():; affiche l'ecran
        ; ClearScreen(0, 0, 0) :;efface l'ecran 
        event=WindowEvent()   
        ;}
        
        If MouseButton(2)
            End
        EndIf 
    Until event=#PB_Event_CloseWindow 
    
    
    Procedure rapide_Point(x,Y)   
        ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF) 
        Select DrawingBufferPixelFormat()  
            Case #PB_PixelFormat_16Bits:PF=2  
                color = PeekW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF ) )  
            Case #PB_PixelFormat_32Bits_RGB    : PF=4
                color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
            Case #PB_PixelFormat_32Bits_BGR    : PF=4
                color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  ) 
                rouge=Red(color)
                vert=Green(color)
                bleu=Blue(color)
                color=RGB(bleu,vert,rouge)  
        EndSelect   
        ProcedureReturn color 
    EndProcedure
    
    Procedure rapide_Plot(x,Y,color)   
        ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF) 
        Select DrawingBufferPixelFormat() 
            Case #PB_PixelFormat_16Bits :PF=2 
                rouge=Red(color)
                vert=Green(color)
                bleu=Blue(color)
                color=RGB(bleu,vert,rouge)   
                color=color>>2   
                PokeW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) , color ) 
            Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0 
                PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color ) 
            Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1  
                rouge=Red(color)
                vert=Green(color)
                bleu=Blue(color)
                color=RGB(bleu,vert,rouge) 
                PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color ) 
        EndSelect   
      EndProcedure

Publié : lun. 02/juin/2008 20:39
par Octavius
Ah! Ca m'intéresse! Lorsque j'essaie de mesurer le temps que ça prend pour ploter les pixels sur mon image, il s'avère que mes fonctions persos ne sont pas plus rapide que le Plot() de PB... :?

Malheureusement tes fonctions ne fonctionnent pas chez moi, il me dit que l'adresse mémoire est invalide. Voici mon code :

Code : Tout sélectionner

Procedure.l ReverseRGB(Color.l)
  ProcedureReturn RGB(Blue(Color),Green(Color),Red(Color))
EndProcedure

Procedure.l PointMemory(Image.l,X.l,Y.l)
  Protected bmp.BITMAP,Color.l,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ProcedureReturn -1
  EndIf
  
  ;Décalage, bits nuls à droite
  Offset=Width*3-Width*3/4*4
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp) : *Address=bmp\bmBits
  
  ;Récupération de la couleur du point
  If *Address
    CopyMemory(*Address+X*Depth+Y*Depth*(Width+Offset),@Color,Depth)
  EndIf
  
  ;Attention à bien inverser les conventions BGR et RGB
  ProcedureReturn ReverseRGB(Color)
  
EndProcedure

Procedure.b PlotMemory(Image.l,X.l,Y.l,Color.l)
  Protected bmp.BITMAP,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ;Echec de l'opération
    ProcedureReturn #False
  EndIf
  
  ;Décalage, bits nuls à droite
  Offset=Width*Depth-Width*Depth/4*4
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp) : *Address=bmp\bmBits
  ;Inversion de la convention RGB et BGR
  Color=ReverseRGB(Color)
  ;Collage du point dans l'image
  If *Address
    CopyMemory(@Color,*Address+X*Depth+Y*Depth*(Width+Offset),Depth)
  EndIf
  ;Réussite de l'opération
  ProcedureReturn #True
  
EndProcedure

Procedure rapide_Point(x,Y)   
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1
    Case  #PB_PixelFormat_24Bits_RGB  : PF=3:t=0
    Case  #PB_PixelFormat_24Bits_BGR  : PF=3:t=1
    Case #PB_PixelFormat_15Bits  : PF=2:t=0    ; 2 octets par pixel
    Case  #PB_PixelFormat_16Bits   : PF=2:t=0 
    Case #PB_PixelFormat_8Bits: PF=1
  EndSelect   
  color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y )  )
  If t=1
    Rouge=Red(color)
    Vert=Green(color)
    Bleu=Blue(color)
    color=RGB(Bleu,Vert,Rouge)
  EndIf
  ProcedureReturn color
EndProcedure

Procedure rapide_Plot(x,Y,color)   
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1
    Case  #PB_PixelFormat_24Bits_RGB  : PF=3:t=0
    Case  #PB_PixelFormat_24Bits_BGR  : PF=3:t=1
    Case #PB_PixelFormat_15Bits  : PF=2:t=0    ; 2 octets par pixel
    Case  #PB_PixelFormat_16Bits   : PF=2:t=0 
    Case #PB_PixelFormat_8Bits: PF=1
  EndSelect 
  If t=1
    Rouge=Red(color)
    Vert=Green(color)
    Bleu=Blue(color)
    color=RGB(Bleu,Vert,Rouge)
  EndIf
  PokeL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) ,color )
EndProcedure

CreateImage(0,295,189,32)
CreateImage(1,295,189,32)
ResizeImage(1,590,398,#PB_Image_Raw)
PlotMemory(0,10,10,$FFFFFF)

Time.l=ElapsedMilliseconds()

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    PlotMemory(1,X,Y,$FFFFFF)
  Next Y
Next X

Time=ElapsedMilliseconds()-Time

Debug Time

CreateImage(1,295,189,32)
ResizeImage(1,590,398,#PB_Image_Raw)

Time=ElapsedMilliseconds()

StartDrawing(ImageOutput(1))

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    Plot(X,Y,$FFFFFF)
  Next Y
Next X

StopDrawing()

Time=ElapsedMilliseconds()-Time

Debug Time

CreateImage(1,295,189,32)
ResizeImage(1,590,398,#PB_Image_Raw)

Time=ElapsedMilliseconds()

StartDrawing(ImageOutput(1))

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    rapide_Plot(X,Y,$FFFFFF)
  Next Y
Next X

StopDrawing()

Time=ElapsedMilliseconds()-Time

Debug Time

SaveImage(0,"image1.bmp")
SaveImage(1,"image2.bmp")

Publié : lun. 02/juin/2008 20:43
par djes
Oui, il y a déjà plusieurs plot "rapides". Celui que je t'ai donné est le plus rapide pour une image (même s'il ne fonctionne apparemment plus avec la version 4.2). Sinon pour ton code sers-toi des champs de la structure bitmap pour avoir la largeur réelle, et aussi le format. Mais cela ne rendra pas ta procédure plus rapide, elle est bien trop longue!

Publié : lun. 02/juin/2008 20:56
par Octavius
Comment faire alors pour la rendre plus rapide ?

Quand tu dis que je dois mieux utiliser les infos de la structure, tu parles de ça ?

Code : Tout sélectionner

bmp\bmWidth
bmp\bmHeight
Ca me donne exactement la même information que ImageWidth() et ImageHeight()...

Publié : lun. 02/juin/2008 21:07
par Backup
Octavius a écrit : Malheureusement tes fonctions ne fonctionnent pas chez moi, il me dit que l'adresse mémoire est invalide. Voici mon code :
Pardon je ne t'ai pas donné la derniere version du Code

avec Cpl.Bator, ce code fut un romand en plusieurs Tome :lol:

j'ai reposté a la place du l'autre code :)

Publié : lun. 02/juin/2008 21:30
par djes
Non, avec bmWidthBytes, qui selon l'affichage courant, te donnera la largeur d'une ligne en octets (ça ne te rappelle rien?)

Publié : lun. 02/juin/2008 21:54
par Octavius
Merci djes! J'ai l'impression que maintenant ça fonctionne!

(Au fait non, ça ne me rappelle rien... :oops: )

Voici mon nouveau code :

Code : Tout sélectionner

Procedure.l ReverseRGB(Color.l)
  ProcedureReturn RGB(Blue(Color),Green(Color),Red(Color))
EndProcedure

Procedure.l PointMemory(Image.l,X.l,Y.l)
  Protected bmp.BITMAP,Color.l,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ProcedureReturn -1
  EndIf
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  Offset=bmp\bmWidthBytes
  
  ;Récupération de la couleur du point
  If *Address
    CopyMemory(*Address+X*Depth+Y*Offset,@Color,Depth)
  EndIf
  
  ;Attention à bien inverser les conventions BGR et RGB
  ProcedureReturn ReverseRGB(Color)
  
EndProcedure

Procedure.b PlotMemory(Image.l,X.l,Y.l,Color.l)
  Protected bmp.BITMAP,Width.l,Height.l,Depth.b,Offset.l,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ;Echec de l'opération
    ProcedureReturn #False
  EndIf
  
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  Offset=bmp\bmWidthBytes
  
  ;Inversion de la convention RGB et BGR
  Color=ReverseRGB(Color)
  ;Collage du point dans l'image
  If *Address
    CopyMemory(@Color,*Address+X*Depth+Y*Offset,Depth)
  EndIf
  ;Réussite de l'opération
  ProcedureReturn #True
  
EndProcedure

Procedure rapide_Point(x,Y)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat() 
      Case #PB_PixelFormat_16Bits:PF=2 
          color = PeekW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF ) ) 
      Case #PB_PixelFormat_32Bits_RGB    : PF=4
          color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
      Case #PB_PixelFormat_32Bits_BGR    : PF=4
          color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
          rouge=Red(color)
          vert=Green(color)
          bleu=Blue(color)
          color=RGB(bleu,vert,rouge) 
  EndSelect
  ProcedureReturn color
EndProcedure

Procedure rapide_Plot(x,Y,color)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_16Bits :PF=2
      rouge=Red(color)
      vert=Green(color)
      bleu=Blue(color)
      color=RGB(bleu,vert,rouge)   
      color=color>>2   
      PokeW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) , color )
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
      PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color )
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1 
      rouge=Red(color)
      vert=Green(color)
      bleu=Blue(color)
      color=RGB(bleu,vert,rouge)
    PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color )
  EndSelect
EndProcedure

; CreateImage(0,295,189,24)
; CreateImage(1,295,189,24)
; ResizeImage(1,590,398,#PB_Image_Raw)
; 
; PlotMemory(0,10,10,$FFFFFF)
; PlotMemory(1,10,10,$FFFFFF)
; 
; SaveImage(0,"image1.bmp")
; SaveImage(1,"image2.bmp")

CreateImage(1,295,189,32)
ResizeImage(1,590,398,#PB_Image_Raw)

Time.l=ElapsedMilliseconds()

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    PlotMemory(1,X,Y,$FFFFFF)
  Next Y
Next X

Time=ElapsedMilliseconds()-Time

Debug Time

;*********************************************

CreateImage(1,295,189,32)
ResizeImage(1,590,398,#PB_Image_Raw)

Time=ElapsedMilliseconds()

StartDrawing(ImageOutput(1))

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    Plot(X,Y,$FFFFFF)
  Next Y
Next X

StopDrawing()

Time=ElapsedMilliseconds()-Time

Debug Time

;*********************************************

CreateImage(1,295,189,32)
ResizeImage(1,590,398,#PB_Image_Raw)

Time=ElapsedMilliseconds()

StartDrawing(ImageOutput(1))

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    rapide_Plot(X,Y,$FFFFFF)
  Next Y
Next X

StopDrawing()

Time=ElapsedMilliseconds()-Time

Debug Time

Dobro, ça y est j'arrive à faire fonctionner tes procédures. Mais bizarrement elle n'est pas si rapide que ça... Je teste les 3 techniques pour remplir une image noir de 590*398 avec des pixels blancs, voici les résultats de mon debug :

PlotMemory(), ma fonction perso : 531 ms
Plot(), la fonction native de PB : 141 ms
rapide_Plot(), la fonction de Cpl.Bator & Dobro : 203 ms

Bizarre, vous pouvez confirmé ? :?

Au moins l'avantage de ma fonction (peut-être le seul... :cry: ) sur les autres c'est que je fais un Plot sans avoir recours aux Start/StopDrawing(), ce qui peut être relativement agréable lorsqu'on manipule beaucoup d'images en même temps...

Publié : lun. 02/juin/2008 22:18
par Anonyme
en debug , c'est pas rapide , remplace debug par messagerequester() , tu veras la vrai différence. la dernière fct° est la + rapide ici. 0ms contre 78ms pour les autres

Publié : lun. 02/juin/2008 22:34
par Octavius
D'accord. Sans le débogueur j'ai 100-145 ms pour les deux premières et 0-16 ms pour la dernière. Soit un Plot 8 fois plus rapide. Je suis vraiment content! Merci beaucoup à vous tous!

EDIT: C'est encore plus net avec une image plus grande : 1024*1024. Cette fois j'utilise GetTickCount_(), plus précis que ElapsedMilliseconds(), et j'obtiens les résultats suivants :
15 ms pour le témoin sans plot
578 ms pour ma fonction PlotMemory() ( :cry: )
531 ms pour le Plot() natif
32 ms pour le rapide_Plot() et Cpl.Bator & Dobro (16-17 fois plus rapide!!!)

Voici mon code pour le test :

Code : Tout sélectionner

Procedure.l ReverseRGB(Color.l)
  ProcedureReturn RGB(Blue(Color),Green(Color),Red(Color))
EndProcedure

Procedure.l PointMemory(Image.l,X.l,Y.l)
  Protected bmp.BITMAP,Color.l,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ProcedureReturn -1
  EndIf
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  Offset=bmp\bmWidthBytes
  
  ;Récupération de la couleur du point
  If *Address
    CopyMemory(*Address+X*Depth+Y*Offset,@Color,Depth)
  EndIf
  
  ;Attention à bien inverser les conventions BGR et RGB
  ProcedureReturn ReverseRGB(Color)
  
EndProcedure

Procedure.b PlotMemory(Image.l,X.l,Y.l,Color.l)
  Protected bmp.BITMAP,Width.l,Height.l,Depth.b,Offset.l,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ;Echec de l'opération
    ProcedureReturn #False
  EndIf
  
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  Offset=bmp\bmWidthBytes
  
  ;Inversion de la convention RGB et BGR
  Color=ReverseRGB(Color)
  ;Collage du point dans l'image
  If *Address
    CopyMemory(@Color,*Address+X*Depth+Y*Offset,Depth)
  EndIf
  ;Réussite de l'opération
  ProcedureReturn #True
  
EndProcedure

Procedure rapide_Point(x,Y)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat() 
      Case #PB_PixelFormat_16Bits:PF=2 
          color = PeekW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF ) ) 
      Case #PB_PixelFormat_32Bits_RGB    : PF=4
          color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
      Case #PB_PixelFormat_32Bits_BGR    : PF=4
          color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
          rouge=Red(color)
          vert=Green(color)
          bleu=Blue(color)
          color=RGB(bleu,vert,rouge) 
  EndSelect
  ProcedureReturn color
EndProcedure

Procedure rapide_Plot(x,Y,color)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_16Bits :PF=2
      rouge=Red(color)
      vert=Green(color)
      bleu=Blue(color)
      color=RGB(bleu,vert,rouge)   
      color=color>>2   
      PokeW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) , color )
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
      PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color )
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1 
      rouge=Red(color)
      vert=Green(color)
      bleu=Blue(color)
      color=RGB(bleu,vert,rouge)
    PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color )
  EndSelect
EndProcedure

; CreateImage(0,295,189,24)
; CreateImage(1,295,189,24)
; ResizeImage(1,590,398,#PB_Image_Raw)
; 
; PlotMemory(0,10,10,$FFFFFF)
; PlotMemory(1,10,10,$FFFFFF)
; 
; SaveImage(0,"image1.bmp")
; SaveImage(1,"image2.bmp")

CreateImage(1,512,512,24)
ResizeImage(1,1024,1024,#PB_Image_Raw)

Time.l=GetTickCount_()

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
  Next Y
Next X

Time=GetTickCount_()-Time

MessageRequester("Témoin sans plot",Str(Time)+" ms")

;*********************************************

CreateImage(1,512,512,24)
ResizeImage(1,1024,1024,#PB_Image_Raw)

Time.l=GetTickCount_()

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    PlotMemory(1,X,Y,$FFFFFF)
  Next Y
Next X

Time=GetTickCount_()-Time

MessageRequester("Ma fonction perso PlotMemory()",Str(Time)+" ms")

;*********************************************

CreateImage(1,512,512,24)
ResizeImage(1,1024,1024,#PB_Image_Raw)

Time=GetTickCount_()

StartDrawing(ImageOutput(1))

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    Plot(X,Y,$FFFFFF)
  Next Y
Next X

StopDrawing()

Time=GetTickCount_()-Time

MessageRequester("La fonction native Plot()",Str(Time)+" ms")

;*********************************************

CreateImage(1,512,512,24)
ResizeImage(1,1024,1024,#PB_Image_Raw)

Time=GetTickCount_()

StartDrawing(ImageOutput(1))

For X=0 To ImageWidth(1)
  For Y=0 To ImageHeight(1)
    rapide_Plot(X,Y,$FFFFFF)
  Next Y
Next X

StopDrawing()

Time=GetTickCount_()-Time

MessageRequester("La fonction de Dobro & Cpl.Bator rapide_Plot()",Str(Time)+" ms")

Publié : lun. 02/juin/2008 23:55
par Backup
tout le mérite en reviens a cpl.bator :D

mon seul merite c'est d'avoir garder ce code au chaud :lol:

Publié : mar. 03/juin/2008 8:33
par djes

Code : Tout sélectionner

CreateImage(1,512,512,24)
Y'aurait pas un souci? :lol:

Un indice? Faudrait peut-être tracer quelque chose pour pouvoir comparer... :twisted:

Publié : mar. 03/juin/2008 8:56
par Octavius
Effectivement!!

La fonction ne trace rien du tout... Et pour cause, elle ne gère pas le 24 bits. Ok, je viens donc d'effectuer un test en 32 bits.

Et là que vois-je ?! 8O Le debug du DrawingBuffer() me donne 0 ! :x

La fonction de Cpl.Bator, si elle rapide, c'est parce qu'elle ne marche pas...

Après vérification ça marche bien avec SpriteOutput(), mais pas avec ImageOutput()...

On dirait qu'il est impossible d'écrire sur une image avec cette technique.