il devrait fonctionner sur la plupart des pc
Code : Tout sélectionner
EnableExplicit
CompilerIf #PB_Compiler_Thread = #False
CompilerError "Enable Thread Safe mode!"
CompilerEndIf
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=800
Global imgy=600
Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=ndt_max
If ndt < 1 : ndt = 1 :EndIf
Global Dim Thread(ndt_max+1)
Structure var
source.i
cible.i
start.l
stop.l
radius.l
intensity.l
EndStructure
Global Dim param.var((ndt_max)*2+1)
Global Dim nr.l(256 + 256 * ndt_max)
Global Dim ng.l(256 + 256 * ndt_max)
Global Dim nb.l(256 + 256 * ndt_max)
Global Dim it.l(256 + 256 * ndt_max)
; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
Protected nom_p.i , temps_p.i , x.l , y.l , r.l,g.l,b.l , i.l
Protected lg.l , ht.l , depth.l , temps.i , dif.l , dif1.l
LoadImage(nom,file$)
If Not IsImage(nom) : ProcedureReturn 0 : EndIf
StartDrawing(ImageOutput(nom))
Depth=OutputDepth()
StopDrawing()
If Depth=24
CopyImage(nom,temps)
FreeImage(nom)
StartDrawing(ImageOutput(temps))
temps_p = DrawingBuffer()
lg = ImageWidth(temps)
ht = ImageHeight(temps)
dif = DrawingBufferPitch() - (lg*3)
Debug dif
StopDrawing()
CreateImage(nom,lg,ht,32)
StartDrawing(ImageOutput(nom))
nom_p = DrawingBuffer()
StopDrawing()
For y=0 To ht-1
For x=0 To lg-1
i = ((y*lg)+x)*3
r=PeekA(temps_p + i + 2 + dif1)
g=PeekA(temps_p + i + 1 + dif1)
b=PeekA(temps_p + i + 0 + dif1)
PokeL(nom_p + ((y*lg)+x)*4 , r<<16 + g<<8 + b)
Next
dif1 = dif1 + dif
Next
FreeImage(temps) ; supprime l'image 24bits
EndIf
ProcedureReturn 1
EndProcedure
;-------------------------------------------------------------------
Macro sp(source,cible)
Protected lg , ht , lg1 , ht1 , taille
Protected cible_p , source_p
StartDrawing(ImageOutput(cible))
cible_p = DrawingBuffer()
ht1 = ImageHeight(cible)
lg1 = ImageWidth(cible)
StopDrawing()
StartDrawing(ImageOutput(source))
source_p = DrawingBuffer()
ht = ImageHeight(source)
lg = ImageWidth(source)
StopDrawing()
If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
taille = lg * ht
EndMacro
Macro returnARGB(pixel,a,r,g,b)
a=(pixel & $ff000000)>>24
r=(pixel & $ff0000)>>16
g=(pixel & $ff00)>>8
b=(pixel & $ff)
EndMacro
Macro clamp(var,min,max)
If var<min : var = min : EndIf
If var>max : var = max : EndIf
EndMacro
;-------------------------------------------------------------------
Procedure OilPainting_sp(i)
Protected i2.l = 0
Protected source.q , cible.q , start.q , stop.q , radius.q , intensity.q
Protected x.q,y.q
Protected pit.l , pnr.l , png.l , pnb.l
pit=it()
pnr=nr()
png=ng()
pnb=nb()
source=param(i)\source
cible=param(i)\cible
start=param(i)\start
stop=param(i)\stop
radius=param(i)\radius
intensity=param(i)\intensity
If intensity<1 : intensity=1 :EndIf
sp(source,cible)
If stop > (ht-1) : stop= ht-1 : EndIf
i = (i * 256)*4
For y=start To stop
!mov r11,[p.v_pit]
!mov r12,[p.v_pnr]
!mov r13,[p.v_png]
!mov r14,[p.v_pnb]
!add r11,[p.v_i]
!add r12,[p.v_i]
!add r13,[p.v_i]
!add r14,[p.v_i]
!xor rax,rax ; For j=0 To intensity : nr(j)=0 : ng(j)=0 : nb(j)=0 : it(j)=0 : Next
!xor rbx,rbx
!mov rcx,[p.v_intensity]
!OilPainting_reset:
!mov [r11+rbx],eax
!mov [r12+rbx],eax
!mov [r13+rbx],eax
!mov [r14+rbx],eax
!add rbx,4
!dec rcx
!jnz OilPainting_reset
!mov rbx,[p.v_radius] ; For yy=-radius To radius
!neg rbx
!OilPainting_saut_yy1:
!mov r15,[p.v_radius] ; For xx=-radius To radius
!neg r15
!OilPainting_saut_xx1:
!xor rax,rax
!mov r8,r15;[p.v_xx]
!cmp r8,[p.v_lg] ;clamp(px,0,lg-1)
!cmovae r8,rax
;py=yy+y
!mov r9,rbx;[p.v_yy]
!add r9,[p.v_y]
!cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
!cmovae r9,rax
;rgb = PeekL(source_p+((py*lg+px)<<2))
!mov r10,r9 ; r9=[p.v_py]
!imul r10,[p.v_lg]
!add r10,r8; r8 = [p.v_px]
!shl r10,2
!add r10,[p.v_source_p]
!mov eax,[r10] ; eax = argb
;ReturnARGB( rgb , index , r , g , b )
!mov edx,eax
!shr edx,24
!and rdx,$ff ; rdx = index
;nb(index) = (nb(index) + b)
!xor ecx,ecx
!mov cl,al
!add [r14+rdx*4],ecx
!shr eax,8
;ng(index) = (ng(index) + g)
!mov cl,al
!add [r13+rdx*4],ecx
!shr eax,8
;nr(index) = (nr(index) + r)
!mov cl,al
!add [r12+rdx*4],ecx
;it(index) = (it(index) + 1)
!mov cl,1
!add [r11+rdx*4],ecx
!inc r15 ;Next
!cmp r15,[p.v_radius]
!jle OilPainting_saut_xx1
!inc rbx;Next
!cmp rbx, [p.v_radius]
!jle OilPainting_saut_yy1
!xor r15,r15
!OilPainting_saut_x1:
;For x=0 To lg-1 ; -----------------------------------------------------------------------------------------------------------
!mov r8,[p.v_radius] ;For yy=-radius To radius ; -------------------------------------------------------------
!neg r8
!OilPainting_saut_y1:
;px=x-radius
!xor rax,rax
!mov rcx,r15 ; [p.v_x]
!sub rcx,[p.v_radius]
!cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
!cmovae rcx,rax ; rcx=px
;py=yy+y
!mov r9,r8;r8 = [p.v_yy]
!add r9,[p.v_y]
!cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
!cmovae r9,rax ; r9=py
;rgb = PeekL(source_p+((py*lg+px)<<2))
!mov r10,r9
!imul r10,[p.v_lg]
!add r10,rcx;[p.v_px]
!shl r10,2
!add r10,[p.v_source_p]
!mov eax,[r10] ; eax = argb
;ReturnARGB( rgb , index , r , g , b )
!mov edx,eax
!shr edx,24
!and rdx,$ff ; rdx = index
;nb(index) = (nb(index) - b)
!xor ecx,ecx
!mov cl,al
!sub [r14+rdx*4],ecx
!shr eax,8
;ng(index) = (ng(index) - g)
!mov cl,al
!sub [r13+rdx*4],ecx
!shr eax,8
;nr(index) = (nr(index) - r)
!mov cl,al
!sub [r12+rdx*4],ecx
;it(index) = (it(index) - 1)
!mov cl,1
!sub [r11+rdx*4],ecx
;px=x+radius+1
!xor rax,rax
!mov rcx,r15 ;[p.v_x]
!add rcx,[p.v_radius]
!inc rcx
!cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
!cmovae rcx,rax
;rgb = PeekL(source_p+((py*lg+px)<<2))
!mov r10,r9; r9 = [p.v_py] = py=yy+y
!imul r10,[p.v_lg]
!add r10,rcx; rcx=[p.v_px]
!shl r10,2
!add r10,[p.v_source_p]
!mov eax,[r10] ; eax = argb
;ReturnARGB( rgb , index , r , g , b )
!mov edx,eax
!shr edx,24
!and rdx,$ff ; rdx = index
;nb(index) = (nb(index) + b)
!xor ecx,ecx
!mov cl,al
!add [r14+rdx*4],ecx
!shr eax,8
;ng(index) = (ng(index) + g)
!mov cl,al
!add [r13+rdx*4],ecx
!shr eax,8
;nr(index) = (nr(index) + r)
!mov cl,al
!add [r12+rdx*4],ecx
;it(index) = (it(index) + 1)
!mov cl,1
!add [r11+rdx*4],ecx
!inc r8;Next
!cmp r8,[p.v_radius]
!jle OilPainting_saut_y1 ; -------------------------------------------------------------
!xor rax,rax; j=0
!xor r8,r8 ; r=0
!xor r9,r9 ; g=0
!xor r10,r10; b=0
!OilPainting_saut_y2: ;For j=0 To intensity
!mov edx,[r11+rax*4] ; edx = it(j)
!cmp edx,[r11+r8*4] ; cmp it(j) , it(r)
!cmovg r8,rax ; if it(j) > it(r) : r = j
!cmp edx,[r11+r9*4]
!cmovg r9,rax
!cmp edx,[r11+r10*4]
!cmovg r10,rax
!inc rax ;Next
!cmp rax,[p.v_intensity]
!jbe OilPainting_saut_y2
!xor rbx,rbx
!mov ecx,[r11+r8*4] ; If it(r)>0 : r=nr(r)/(it(r)) : EndIf
!cmp ecx,0
!jz OilPainting_saut_r
!mov eax,[r12+r8*4] ; eax = nr(r)
!cqo
!idiv ecx
!mov bl,al
!shl ebx,16
!OilPainting_saut_r:
!mov ecx,[r11+r9*4] ; If it(g)>0 : g=ng(g)/(it(g)) : EndIf
!cmp ecx,0
!jz OilPainting_saut_g
!mov eax,[r13+r9*4] ; eax = ng(g)
!cqo
!idiv ecx
!mov bh,al
!OilPainting_saut_g:
!mov ecx,[r11+r10*4] ; If it(b)>0 : b=nb(b)/(it(b)) : EndIf
!cmp ecx,0
!jz OilPainting_saut_b
!mov eax,[r14+r10*4] ; eax = nb(b)
!cqo
!idiv ecx
!mov bl,al
!OilPainting_saut_b:
;PokeL(cible_p+((y*lg+x)<<2), b)
!xor rax,rax
!mov eax,[p.v_y]
!imul eax,[p.v_lg]
!add eax,r15d;[p.v_x]
!shl eax,2
!add rax,[p.v_cible_p]
!mov [rax],ebx
!inc r15
!cmp r15,[p.v_lg]
!jb OilPainting_saut_x1
;Next ; -----------------------------------------------------------------------------------------------------------
Next
EndProcedure
;-------------------------------------------------------------------
Procedure OilPainting(source.i,cible.i,radius.l,intensity.l)
Protected div.l , i.l , x.l , y.l
Protected rgb.l , a.l , r.l , g.l , b.l
Protected tt.l
sp(source,cible)
For y=0 To ht-1
For x=0 To lg-1
rgb = PeekL(source_p+((y*lg+x)<<2))
Returnargb( rgb , a , r , g , b )
a = (( r + g + b ) * 85)>>8
a = (( a * intensity )>>8) & 255
PokeL(source_p+((y*lg+x)<<2),a<<24 + (rgb & $00ffffff))
Next
Next
div=ht/ndt
For i=0 To ndt-1
Param(i)\source=source
Param(i)\cible=cible
Param(i)\radius=radius
Param(i)\intensity=intensity
Param(i)\start=i*div
If i = (ndt-1)
Param(i)\stop=ht-1
Else
Param(i)\stop=(i*div)+div-1
EndIf
Thread(i)=CreateThread(@OilPainting_sp(),i)
Next
For i=0 To ndt-1
If Thread(i) : WaitThread(thread(i)):EndIf
Next
EndProcedure
;-------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=800
Global imgy=600
If OpenWindow(0, 0, 0, imgx, imgy, "OilPainting", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define source.i=0 , cible.i=0 , t.i , file$ , nom$ , quit.l
Define ht1.l , lg1.l
CreateMenu(0, WindowID(0))
MenuTitle("Load")
MenuItem( 1, "Load")
MenuTitle("Save")
MenuItem( 2, "Save BMP")
;MenuItem( 3, "Save JPG")
MenuItem( 4, "Save Clipboard")
MenuTitle("Quit")
MenuItem( 5, "Quit")
ScrollBarGadget(100, 50, 0, 250, 18, 0, 10, 1)
ScrollBarGadget(101, 400, 0, 250, 18, 0, 255, 1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 100 , 101
t=ElapsedMilliseconds()
OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
t=ElapsedMilliseconds()-t
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case 1
If source = 0
source = 10
Else
FreeImage((source))
FreeImage((cible))
cible = 0
EndIf
file$ = OpenFileRequester("Image","","",0)
If Not Load_Image(source,file$)
MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
Else
If cible = 0 And source = 10
cible = 20
CopyImage(source,cible)
EndIf
OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
EndIf
Case 2
nom$ = SaveFileRequester("Save BMP", "", "", 0)
If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf
Case 3
;SaveFileRequester("Save JPG", "", "", 0)
;If nom$ <> "" : SaveImage(cible, nom$+".jpg" ,#PB_ImagePlugin_JPEG ,10 ) : EndIf
Case 4
SetClipboardImage(cible)
Case 5
quit = 1
EndSelect
EndSelect
StartDrawing(WindowOutput(0))
If cible<>0
DrawImage(ImageID(cible),0,20)
EndIf
DrawText(5,2,Str(t)+" ")
StopDrawing()
Until Quit = 1
EndIf