Publié : mar. 06/juin/2006 17:49
un petit peu de temps, voilà la source :
La fonction GetImageBits permet de transformer une image sous forme de tableau. on peut ainsi y accéder nettement plus rapidement pour lire les couleurs et savoir si elle est mauve ou non.
En groupant les procedures GetImageBit et SkinWindow, on doit pouvoir aller encore plus vite car cela supprimerait toute la partie de conversion de l'image pour la rendre facilement exploitable. on doit pouvoir gagner encore 30% je pense.
Je suis dessus.
Code : Tout sélectionner
Procedure.l GetImageBits2(ImageID, HList) ; Transfert d'une image vers un tableau
Protected bmi.BITMAPINFO, hdc.l, Resultat, Mem, n, nn, bm.BITMAP, Temp1, Temp2, Temp3, Temp4
Resultat = 0
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
hdc = CreateCompatibleDC_(GetDC_(ImageID))
If hdc
GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
DeleteDC_(hdc)
Resultat = ImageID
EndIf
; On convertit la liste dans le bon format
Temp1 = bm\bmHeight - 1
Temp2 = bm\bmWidth - 1
For nn = 0 To Temp2
For n = 0 To Temp1
Temp3 = Mem + (nn + (Temp1 - n) * bm\bmWidth) * 4
PokeB(HList + 2, PeekB(Temp3))
PokeB(HList + 1, PeekB(Temp3 + 1))
PokeB(HList, PeekB(Temp3 + 2))
HList + 4
Next
Next
FreeMemory(Mem)
EndIf
ProcedureReturn Resultat
EndProcedure
Procedure SkinWindow2(Window, Image) ; Mettre une forme sur une fenêtre a partir d'une image
Protected Region_Temp, Region_Totale, Largeur, Hauteur
; On applique le skin à la fenêtre
Largeur = ImageWidth(Image) - 1
Hauteur = ImageHeight(Image) - 1
Region_Totale = CreateRectRgn_(0, 0, Largeur + 1, Hauteur + 1) ; on crée une region de la taille de la fenêtre
Dim Region_Image.l(Largeur, Hauteur)
GetImageBits2(ImageID(Image), @Region_Image())
For X1 = 0 To Largeur
For Y1 = 0 To Hauteur
If Region_Image(X1, Y1) = $FF00FF
Y2 = Y1
While X2 < Largeur And Region_Image(X1, Y2 + 1) = $FF00FF
Y2 + 1
Wend
Region_Temp = CreateRectRgn_(X1, Y1, X1 + 1, Y2 + 1) ; On retire le point de la region
CombineRgn_(Region_Totale, Region_Totale, Region_Temp, #RGN_DIFF)
DeleteObject_(Region_Temp)
Y1 = Y2
EndIf
Next
Next
SetWindowRgn_(WindowID(Window), Region_Totale, 1) ; On applique la region
DeleteObject_(Region_Totale) ; On efface la region
EndProcedure
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 300, 300, "Skin", #PB_Window_BorderLess | #PB_Window_ScreenCentered) = 0 Or CreateGadgetList(WindowID(0)) = 0
End
EndIf
; La fenêtre doit obligatoirement être avec le style #PB_Window_BorderLess
SetWindowColor(0, RGB(255, 0, 0))
; On crée une image qui va servir de skin (elle doit avoir la taille de la fenêtre)
CreateImage(0, 300, 300)
StartDrawing(ImageOutput(0))
; La couleur mauve $FF00FF ou RGB(255, 0, 255) représente la partie transparente de la fenêtre
Box(250, 0, 50, 30, $FF00FF)
Circle(200, 200, 50, $FF00FF)
Circle(250, 230, 50, $FF00FF)
Ellipse(50, 120, 40, 20, $FF00FF)
LineXY(50, 50, 250, 100, $FF00FF)
StopDrawing()
Temps = ElapsedMilliseconds()
SkinWindow2(0, 0)
Temps = ElapsedMilliseconds() - Temps
; On place un bouton pour quitter
ButtonGadget(0, 0, 0, 100, 25, "Quitter")
; On affichage le temps nécesssaire pour créer le masque
TextGadget(#PB_Any, 0, 25, 100, 15, Str(Temps) + " ms")
Repeat
Event = WaitWindowEvent()
If Event = #WM_LBUTTONDOWN
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndIf
If Event = #PB_Event_Gadget
Select EventGadget() ; boutons, zone de texte, ...
Case 0 ; On quitte le programme
Event = #PB_Event_CloseWindow
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
End
En groupant les procedures GetImageBit et SkinWindow, on doit pouvoir aller encore plus vite car cela supprimerait toute la partie de conversion de l'image pour la rendre facilement exploitable. on doit pouvoir gagner encore 30% je pense.
Je suis dessus.