Page 1 sur 1

[resolu] Effacer une partie d'une image ?

Publié : sam. 16/juil./2011 22:46
par blendman
salut

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 :D.


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
;}

Re: Effacer une partie d'une image ?

Publié : dim. 17/juil./2011 15:49
par SPH
Tu es trop productif, on n'arrive pas a te suivre :mrgreen:

Re: Effacer une partie d'une image ?

Publié : lun. 18/juil./2011 12:21
par blendman
Bon, j'ai réussi :)
Avec les custom_filter et le drawingmode(#pb_2ddrawing_customfilter)

C'est bien classe :)