J'ai un bug que j'ai du mal à résoudre :
J'essaie de réaliser une gomme, mais je n'y parviens pas.
En gros, voici ce que je chercher à obtenir :
- je dessine sur un calque (une image transparente)
- je montre à l'écran (sur l'imagegadget représentant tous les calques) les calques du dessous (ici le checkker), mon calque sur lequel je dessine et les calque du dessus.
ça à priori, ça fonctionne à peu près je crois.
- j'ai essayé de créer une gomme qui devrait gommer le calque sur lequel je suis, mais là, ça bug complètement
Si quelqu'un a une idée, ce serait super

Code : Tout sélectionner
;{ enumeration, constante
#canW=800
#canH=800
;images
Enumeration
#img0
#brush
#preview
#motif
#copybrush1
#copybrush
#img_final = 100
#layer1 =11
#layer2=12
#bg = 50
#saveimage = 500
EndEnumeration
;gadget
Enumeration
#scroll
EndEnumeration
;}
;{ variable
Global size = 300, quit, clscolor, preview_size=64, cursor, random_size, transparence.a=255, brushid = 9, brush_dir$="blendman",brush_nb
Global canvas,mouseincanvas,x,y,igad,clscolor,xx,yy, drawmode, open_menu.b
;}
;{ declare
Declare DrawBrush(can,xpos,ypos)
Declare ClsCanvas(can,r,g,b)
Declare random_resize()
Declare.l RotateImageEx2(ImageID, Angle.f, Mode.l=2)
Declare event_paint()
;}
;{ init
If UsePNGImageDecoder() =0 Or UseJPEGImageDecoder() =0 Or UseJPEGImageEncoder()=0 Or UsePNGImageEncoder()=0
End
EndIf
;}
;{ images
; motif
CreateImage(#motif,64,64)
StartDrawing(ImageOutput(#motif))
Box(0,0,32,32,RGB(200,200,200))
Box(32,0,32,32,RGB(100,100,100))
Box(32,32,32,32,RGB(200,200,200))
Box(0,32,32,32,RGB(100,100,100))
StopDrawing()
repetx =Round(#canW/64,1)
repety =Round(#canH/64,1)
canvas=CreateImage(#PB_Any,#canW,#canH,32)
StartDrawing(ImageOutput(canvas))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,#canW,#canH,RGBA(125,125,125,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For i=0 To repetx
For j = 0 To repety
DrawAlphaImage(ImageID(#motif),i*64,j*64)
Next j
Next i
StopDrawing()
CreateImage(#bg,#canW,#canH)
StartDrawing(ImageOutput(#bg))
DrawingMode(#PB_2DDrawing_AllChannels)
For i=0 To repetx
For j = 0 To repety
DrawAlphaImage(ImageID(#motif),i*64,j*64)
Next j
Next i
StopDrawing()
; layer
CreateImage(#img_final,#canW,#canH,32)
StartDrawing(ImageOutput(#img_final))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,#canW,#canh,RGBA(0,0,0,0))
StopDrawing()
; brush
CreateImage(#brush,128,128,32)
StartDrawing(ImageOutput(#brush))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,#canW,#canh,RGBA(255,255,255,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Ellipse(64,64,50,25,RGBA(255,255,255,255))
StopDrawing()
ResizeImage(#brush,preview_size,preview_size,#PB_Image_Smooth)
CreateImage(#copybrush,32,32,32); brush_copy avec lequel on peint - a brush copy to paint with
; preview le preview du brush
CreateImage(#preview,preview_size,preview_size,32)
StartDrawing(ImageOutput(#preview))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,preview_size,preview_size,RGBA(125,125,125,0))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,preview_size,preview_size,RGB(255,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawAlphaImage(ImageID(#brush),0,0)
StopDrawing()
;}
;{ openwindow
If OpenWindow(0, 0,0,#canW+46+100, #canH+66, "Canvas",#PB_Window_SystemMenu | #PB_Window_TitleBar|#PB_Window_ScreenCentered) =0
End
EndIf
SmartWindowRefresh(0,1)
;{ image gadget ("canvas")
;ScrollAreaGadget(#scroll,20,20,600,600,850,850,30) ;<<<<<<<<<< bug avec image gadget :(
igad=ImageGadget(#PB_Any, 20, 20, 800, 800, ImageID(canvas),#PB_Image_Border)
;CloseGadgetList()
;}
;{ status bar
If CreateStatusBar(0,WindowID(0))
AddStatusBarField(#PB_Ignore)
StatusBarText(0, 0, "")
EndIf
;}
;{ preview brush
ImageGadget(1,#canw+40,20,64,64,ImageID(2),#PB_Image_Border)
rotation = RotateImageEx2(ImageID(5),r )
random_resize()
;}
;{ menu
If CreateMenu(0,WindowID(0))
MenuTitle("Tools")
MenuItem(0,"Brush +"+Chr(9)+"(X)")
MenuItem(1,"Brush -"+Chr(9)+"(C)")
MenuItem(2,"Size of the Brush"+Chr(9)+"(S)")
MenuItem(3,"Random the Size"+Chr(9)+"(D)")
MenuItem(4,"Transparence"+Chr(9)+"(T)")
MenuTitle("save")
MenuItem(10, "save image")
EndIf
;}
;{ shortcut keyboard
AddKeyboardShortcut(0,#PB_Key_X,0) ; brush +
AddKeyboardShortcut(0,#PB_Key_C,1) ; brush -
AddKeyboardShortcut(0,#PB_Key_S,2) ; change size
AddKeyboardShortcut(0,#PB_Key_D,3) ; change size
AddKeyboardShortcut(0,#PB_Key_T,4) ; Transparence
AddKeyboardShortcut(0,#PB_Key_A,10) ; save
;}
;}
Repeat
event_paint()
Until quit=1
End
;{ procedure
Procedure.l RotateImageEx2(ImageID, Angle.f, Mode.l=2) ; Rotation d'une image d'un angle en °
; merci LSI
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.l, NewImageID, Mem, n, nn, bm.BITMAP
Angle = Angle * #PI / 180 ; On convertit en radian
Cos.f = Cos(Angle)
Sin.f = Sin(Angle)
CouleurFond = 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
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
; Select Mode
; Case 1
; bmi2\bmiHeader\biWidth = bm\bmWidth
; bmi2\bmiHeader\biHeight = bm\bmHeight
; Case 2
bmi2\bmiHeader\biWidth = Round(Sqr(bm\bmWidth * bm\bmWidth + bm\bmHeight * bm\bmHeight), 1)
bmi2\bmiHeader\biHeight = bmi2\bmiHeader\biWidth
; Default
; bmi2\bmiHeader\biWidth = Round(bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin), 1)
; bmi2\bmiHeader\biHeight = Round(bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin), 1)
; EndSelect
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
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)
EndIf
CX1 = bm\bmWidth - 1
CY1 = bm\bmHeight - 1
CX2 = bmi2\bmiHeader\biWidth - 1
CY2 = bmi2\bmiHeader\biHeight - 1
Mem01 = Mem + bm\bmWidth * 4
Mem10 = Mem + 4
Mem11 = Mem01 + 4
Mem2Temp = Mem2
For nn = 0 To CY2
y1b.l = nn * 2 - CY2
Temp1.f = CX1 - y1b * Sin
Temp2.f = CY1 + y1b * Cos
For n = 0 To CX2
x1b.l = n * 2 - CX2
x1.f = (Temp1 + x1b * Cos) / 2
y1.f = (Temp2 + x1b * Sin) / 2
x2.l = x1
y2.l = y1
If x1 < x2
x2-1
EndIf
If y1 < y2
y2-1
EndIf
x2b = x2 + 1
y2b = y2 + 1
If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est completement en dehors de l'image
fx.f = x1 - x2
fy.f = y1 - y2
f00.f = (1 - fx) * (1 - fy)
f01.f = (1 - fx) * fy
f10.f = fx * (1 - fy)
f11.f = fx * fy
MemTemp = (x2 + y2 * bm\bmWidth) * 4
If x2 >= 0 And x2 <= CX1
If y2 >= 0 And y2 <= CY1
c00 = PeekL(Mem + MemTemp)
Else
c00 = 0
EndIf
If y2b >= 0 And y2b <= CY1
c01 = PeekL(Mem01 + MemTemp)
Else
c01 = 0
EndIf
Else
c00 = 0
c01 = 0
EndIf
If x2b >= 0 And x2b <= CX1
If y2 >= 0 And y2 <= CY1
c10 = PeekL(Mem10 + MemTemp)
Else
c10 = 0
EndIf
If y2b >= 0 And y2b <= CY1
c11 = PeekL(Mem11 + MemTemp)
Else
c11 = 0
EndIf
Else
c10 = 0
c11 = 0
EndIf
Channel00 = c00 >> 24 & $FF
Channel01 = c01 >> 24 & $FF
Channel10 = c10 >> 24 & $FF
Channel11 = c11 >> 24 & $FF
Alpha = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
Channel00 = c00 >> 16 & $FF
Channel01 = c01 >> 16 & $FF
Channel10 = c10 >> 16 & $FF
Channel11 = c11 >> 16 & $FF
Rouge = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
Channel00 = c00 >> 8 & $FF
Channel01 = c01 >> 8 & $FF
Channel10 = c10 >> 8 & $FF
Channel11 = c11 >> 8 & $FF
Vert = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
Channel00 = c00 & $FF
Channel01 = c01 & $FF
Channel10 = c10 & $FF
Channel11 = c11 & $FF
Bleu = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
PokeL(Mem2Temp, Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
Else
PokeL(Mem2Temp, 0)
EndIf
Mem2Temp + 4
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight, 32)
hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
If hdc
SetDIBits_(hdc, ImageID(NewImageID), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
DeleteDC_(hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
Procedure random_resize()
siz =20+Random(size-20)*(1-random_size) + random_size*80
CopyImage(1,5)
ResizeImage(5,siz,siz,0)
EndProcedure
Procedure DrawBrush(can,xpos,ypos)
If mouseincanvas=1 And open_menu = 0
random_resize()
r=Round(Random(360),0)
rotation = RotateImageEx2(ImageID(5),r)
x1 = ImageWidth(rotation)/2
y1 = ImageHeight(rotation)/2
StartDrawing(ImageOutput(100))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawAlphaImage(ImageID(rotation),xpos-x1,ypos-y1,transparence)
StopDrawing()
StartDrawing(ImageOutput(can))
DrawingMode(#PB_2DDrawing_Default)
DrawImage(ImageID(#bg),0,0)
;DrawingMode(#PB_2DDrawing_AlphaChannel)
; Box(0,0,#canW,#canH,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawAlphaImage(ImageID(100),0,0)
StopDrawing()
SetGadgetState(igad,ImageID(can))
FreeImage(rotation)
EndIf
EndProcedure
Procedure EraseBrush(can,xpos,ypos)
If mouseincanvas=1 And open_menu = 0
random_resize()
r=Round(Random(360),0)
rotation = RotateImageEx2(ImageID(5),r)
x1 = ImageWidth(rotation)/2
y1 = ImageHeight(rotation)/2
StartDrawing(ImageOutput(100))
; DrawingMode(#PB_2DDrawing_AlphaChannel)
; Box(0,0,#canW,#canH,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaChannel)
DrawAlphaImage(ImageID(rotation),xpos-x1,ypos-y1,transparence)
StopDrawing()
StartDrawing(ImageOutput(can))
DrawingMode(#PB_2DDrawing_Default)
DrawImage(ImageID(#bg),0,0)
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,#canW,#canH,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaChannel)
DrawAlphaImage(ImageID(100),0,0)
StopDrawing()
;
SetGadgetState(igad,ImageID(can))
FreeImage(rotation)
EndIf
EndProcedure
Procedure ClsCanvas(can,r,g,b)
Static bkgcolor
bkgcolor=RGB(r,g,b)
StartDrawing(ImageOutput(100))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,#canW,#canH,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,#canW,#canH,bkgcolor)
StopDrawing()
StartDrawing(ImageOutput(can))
DrawImage(ImageID(100),0,0)
StopDrawing()
SetGadgetState(igad,ImageID(can))
EndProcedure
Procedure event_paint()
ev=WaitWindowEvent()
;{ x , y position of the mouse
x=WindowMouseX(0)-20-5 : y=WindowMouseY(0)-20-24
xx = WindowMouseX(0)
yy =WindowMouseY(0)
If (x>=-150 And x<#canW+150) And (y>=-150 And y<#canH+120)
mouseincanvas=1
StatusBarText(sb, 0, "Coords: "+Str(x)+","+Str(y))
Else
mouseincanvas=0
StatusBarText(sb, 0, "Coords: xxx,xxx")
EndIf
;}
Select ev
;{ event menu
Case #PB_Event_Menu
Select EventMenu()
Case 2 ; key S
open_menu =3
size = Val(InputRequester("Size","Size of the brush",Str(size)))
If size <=0
size = 1
ElseIf size > 500
size =500
EndIf
Case 3 ; key D
random_size = 1-random_size
Case 4
open_menu =3
transparence = Val(InputRequester("transparence","transparence of the brush",Str(transparence)))
If transparence <=0
transparence = 1
ElseIf transparence > 255
transparence=255
EndIf
Case 10
SaveImage(canvas,"savecanvas.png",#PB_ImagePlugin_PNG)
SaveImage(#preview,"brush.png",#PB_ImagePlugin_PNG)
EndSelect
;}
Case #PB_Event_Gadget
If EventGadget()
Select EventType()
Case #PB_EventType_LeftClick
drawmode=1
If open_menu =3
open_menu = 2
ElseIf open_menu =2
open_menu =0
EndIf
Case #PB_EventType_RightClick
drawmode=2
EndSelect
EndIf
Case #WM_LBUTTONUP
drawmode=0
Case #WM_RBUTTONUP
drawmode=0
Case #WM_MOUSEMOVE
If drawmode=1
DrawBrush(canvas,xx,yy)
ElseIf drawmode=2
EraseBrush(canvas,xx,yy)
EndIf
Case #PB_Event_CloseWindow
quit=1
EndSelect
EndProcedure
;}