Page 1 sur 1

Zoom et canvas bug

Publié : dim. 19/juil./2015 13:34
par blendman
salut

je suis parti d'un code de Kernadec, que j'ai modifié afin d'obtenir un zoom avec un canvas.
L'idée :
- lorsqu'on zoom, au lieu d'agrandir toute l'image, j'agrandis uniquement la partie de l'image visible.
- lorsque je déplace l'image, je dois faire un update de la partie à afficher.
C'est particulièrement utile pour de grandes images (> 1024*1024 par exemple), avec un zoom en 500%, ça évite d'avoir une image qui fasse 5*1024 X 5*1024 à afficher. On n'affiche que sur la portion de notre écran.
On pourrait donc travailler sur des images en 10000*10000 sans problème car en réalité, on n'afficherait toujours que du 1200*800 environ (en fait, ça dépendrait de notre résolution et de quelques paramètres (tailles des panels si on en mets sur les cotés...)).

Cependant, j'ai quelques bugs avec ce code et je ne parviens pas à les résoudre (je tâtonne ^^). Donc si quelqu'un comprend comment modifier ça, ça pourrait être super utile pour utiliser de grandes images avec le canvas et les images, ce qui est un des gros problèmes actuellement :).

Code : Tout sélectionner

;{ Infos
; code de kernadec, 
; modifié par blendman 2015
;}

;{ constantes
#Window = 0
Enumeration ; images
  #Image0 
  #Image1
EndEnumeration

Enumeration ; gadgets
  #Scroll
  #canvas
EndEnumeration
;}

Global PosYm1, PosXm1, delta

;{ Procedures

Procedure UpdateCanvas(x=0,y=0)
  
  ; puis on update le canvas
  If StartDrawing(CanvasOutput(#canvas))
    Box(-20,-20,WindowWidth(#Window)*2,WindowHeight(#Window)*2,RGB(255,255,255))
    ; DrawAlphaImage(ImageID(#Image0),PosXm1+(delta/2),PosYm1+(delta/2),255)
    DrawAlphaImage(ImageID(#Image1),x,y)
    StopDrawing()
  EndIf
  
EndProcedure

;}


UseJPEGImageDecoder()
file$ = OpenFileRequester("image","","jpg|*.jpg",0)


If file$ <> ""
  LoadImage(#Image0, file$)
  CreateImage(#Image1,ImageWidth(#Image0),ImageHeight(#Image0),32,#PB_Image_Transparent)
  
  CopyImage(#Image0,#Image1)               ;  crée une copie de l'image pour eviter la degradation de resize
  
  If OpenWindow(#Window,0, 0,ImageWidth(#Image0)+20,ImageHeight(#Image0)+20, "Zoom Canvas ScrollArea clic deplace  Kernadec", 
                #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget)
    
    If ScrollAreaGadget(#Scroll, 0, 0,WindowWidth(#Window),WindowHeight(#Window),ImageWidth(#Image0),ImageHeight(#Image0),30)
      SetWindowColor(#Window,#White)
      If CanvasGadget(#canvas, 0, 0,ImageWidth(#Image0),ImageHeight(#Image0),#PB_Canvas_Keyboard)
      EndIf
      SetGadgetAttribute(#Scroll,#PB_ScrollArea_X,(ImageWidth(#Image0)-WindowWidth(#Window))/2)
      SetGadgetAttribute(#Scroll,#PB_ScrollArea_Y,(ImageHeight(#Image0)-WindowHeight(#Window))/2)
      ; SetActiveGadget(#canvas)             ; focus Canvas : MouseWheel     
      UpdateCanvas(0)
      CloseGadgetList()
    EndIf
    bm=#False
    
    Repeat
      
      Event= WaitWindowEvent()
      
      Select event
          
        Case #PB_Event_Gadget
          
          Select EventGadget()
              
            Case #canvas
              
              Select EventType() 
                  
                Case #PB_EventType_MouseWheel                  
                  delta=delta+(GetGadgetAttribute(#canvas,#PB_Canvas_WheelDelta )*10) ; delta*10
                  If PosXm1+(delta/2) > 0
                    x1 = PosXm1+(delta/2)
                  EndIf
                  If PosYm1+(delta/2) > 0
                    y1 = PosYm1+(delta/2)
                  EndIf
                  If x1 > 0 And y1 > 0
                    ratio.d = ImageHeight(#Image0)/ImageWidth(#Image0)
                    w = ImageWidth(#Image0)-delta                      
                    h = ImageHeight(#Image0)-delta*ratio 
                    If w > ImageWidth(#Image0)
                      w = ImageWidth(#Image0)
                      w1 = w + delta
                    Else
                      w1 = ImageWidth(#Image0)
                    EndIf 
                    If h > ImageHeight(#Image0)
                      h = ImageHeight(#Image0)
                      h1 = h + delta*ratio
                    Else
                      h1 = ImageHeight(#Image0)
                    EndIf
                    ; Debug Str(w)+"/"+Str(h)
                    GrabImage(#Image0,#Image1,x1,y1,w,h)
                    ; on calcule pour resizer l'image si notre nouvelle image est plus grande ou plus petite.ON ne recalcule l'image que si elle est plus grande.
                    ResizeImage(#Image1,w1,h1,#PB_Image_Raw) 
                                        
                  EndIf
                  UpdateCanvas(0,0)
                  
                  
                Case #PB_EventType_LeftButtonDown  ; choix du bouton deplacer
                  bm=#True
                  PosXm = GetGadgetAttribute(#canvas,#PB_Canvas_MouseX)-PosXm1
                  PosYm = GetGadgetAttribute(#canvas,#PB_Canvas_MouseY)-PosYm1 
                  
                Case #PB_EventType_MouseMove       ; deplacement
                  If bm=#True 
                    If space= 1
                      PosXm1 = GetGadgetAttribute(#canvas,#PB_Canvas_MouseX)-PosXm
                      PosYm1 = GetGadgetAttribute(#canvas,#PB_Canvas_MouseY)-PosYm
                      x = PosXm1 ;+(delta/2)
                      y = PosYm1 ;+(delta/2)                     
                      If StartDrawing(CanvasOutput(#canvas))
                        Box(-20,-20,WindowWidth(#Window)*2,WindowHeight(#Window)*2,RGB(255,255,255))
                        DrawAlphaImage(ImageID(#Image1),x,y,255)
                        StopDrawing()
                      EndIf
                    Else
                    EndIf
                  
                  EndIf
                  
                  
                Case #PB_EventType_LeftButtonUp                 
                  If bm = #True
                    bm=#False 
                    If delta > 0
                      x1 = PosXm1 - PosXm
                      If x1 < 0
                        x1 = 0
                      EndIf                      
                      y1 = PosYm1 - PosYm
                      If y1 < 0 
                        y1 = 0
                      EndIf
                      ratio.d = ImageHeight(#Image0)/ImageWidth(#Image0)
                      w = ImageWidth(#Image0)-delta                      
                      h = ImageHeight(#Image0)-delta*ratio                     
                      GrabImage(#Image0,#Image1,x1,y1,w,h)
                      ResizeImage(#Image1,ImageWidth(#Image0),ImageHeight(#Image0),#PB_Image_Raw) 
                      UpdateCanvas(0,0)
                    EndIf
                  EndIf
                  
                  
                Case #PB_EventType_KeyUp
                  space = 0
                  
                  
                Case #PB_EventType_KeyDown      ; deplacement
                  key = GetGadgetAttribute(#canvas,#PB_Canvas_Key)
                  If key = 32 ; space
                    space= 1
                  EndIf
                  
                  
              EndSelect 
              
          EndSelect
          
        Case #PB_Event_SizeWindow
          
          ResizeGadget(#Scroll,#PB_Ignore,#PB_Ignore,WindowWidth(#Window),WindowHeight(#Window))
          win_w=WindowWidth(#Window)
          win_h=WindowHeight(#Window)
          
      EndSelect 
      
    Until Event= #PB_Event_CloseWindow
    End
    
  EndIf
    
EndIf
Merci ;).

Re: Zoom et canvas bug

Publié : dim. 19/juil./2015 15:56
par blendman
tu as entièrement raison, et c'est d'ailleurs ce que j'essaie d'obtenir avec le canvas ;).

Mais pour le moment, les zooms que j'ai trouvé sont en général des zooms d'image entières (agrandissement d'images et donc de tous les pixels), notamment sur le fichier original de kernadec, pour zoomer, ça faisait un ResizeImage() avec le pourcentage du zoom * W ou H , d'où ce que j'ai écrit ^^.
Moi, j'essaie d'arriver plus ou moins à ta technique, ou en tout d'éviter d'agrandir l'image, de n'afficher que la surface et zoomer celle-ci. Mais ta technique serait encore mieux certainement.
Cela signifie que tu gères l'affichage avec des box() et un tableau par exemple ? Ou tu utiliserais une autre technique ?

Re: Zoom et canvas bug

Publié : dim. 19/juil./2015 17:19
par blendman
Yep, j'étais arrivé un peu à ce genre de chose. Marrante l'idée du zoomX et Y, c'est vrai que ça permet d'avoir des effets.

Voici le test que j'avais fait, mais au zoom = 13,14,15, j'ai une grille blanche qui apparait :( :

Code : Tout sélectionner


;{ Infos
; code blendman 2015 sur une idée de spock-dobro :)
; basé sur un code de kernadec 
;}

;{ constantes
#Window = 0
Enumeration ; images
  #Image0 
  #Image1
EndEnumeration

Enumeration ; gadgets
  #Scroll
  #canvas
EndEnumeration
;}

Global PosYm1, PosXm1, delta
Global Dim Pixel(0,0)
Global X1,Y1,W1,H1, zoom
Zoom = 10
delta = 10

;{ Procedures

Procedure UpdateCanvas()
  
  z.d = zoom*0.1
  
  ; puis on update le canvas
  If StartDrawing(CanvasOutput(#canvas))
    Box(-20,-20,WindowWidth(#Window)*2,WindowHeight(#Window)*2,RGB(255,255,255))
    If z > 1
      For i = x1 To W1-1
        For j = y1 To H1-1
          Box(i*z,j*z,z,z, Pixel(i,j))             
        Next 
      Next 
    Else
      DrawImage(ImageID(#image0),0,0,w1,h1)
    EndIf
    StopDrawing()
  EndIf
  
EndProcedure

;}


UseJPEGImageDecoder()
UsePNGImageDecoder()
file$ = OpenFileRequester("Open Image","","Images|*.jpg;*.png;*.bmp",0)


If file$ <> ""
  
  LoadImage(#Image0, file$)
  w = ImageWidth(#Image0)
  h = ImageHeight(#Image0)
  w1 = w
  h1 = h
  
  If StartDrawing(ImageOutput(#Image0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    Dim Pixel(w1,h1)
    For i=0 To w1-1
      For j =0 To h1-1
        pixel(i,j)=Point(i,j)
      Next 
    Next 
    StopDrawing()
  EndIf
  
  If OpenWindow(#Window,0, 0,ImageWidth(#Image0)+20,ImageHeight(#Image0)+20, "Zoom Canvas ScrollArea clic deplace  Kernadec", 
                #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget)
    
    If ScrollAreaGadget(#Scroll, 0, 0,WindowWidth(#Window),WindowHeight(#Window),ImageWidth(#Image0),ImageHeight(#Image0),30)
      SetWindowColor(#Window,#White)
      If CanvasGadget(#canvas, 0, 0,ImageWidth(#Image0),ImageHeight(#Image0),#PB_Canvas_Keyboard)
      EndIf
      SetGadgetAttribute(#Scroll,#PB_ScrollArea_X,(ImageWidth(#Image0)-WindowWidth(#Window))/2)
      SetGadgetAttribute(#Scroll,#PB_ScrollArea_Y,(ImageHeight(#Image0)-WindowHeight(#Window))/2)
      UpdateCanvas()
      CloseGadgetList()
    EndIf
    bm=#False
    
    Repeat
      
      Event= WaitWindowEvent()
      
      Select event
          
        Case #PB_Event_Gadget
          
          Select EventGadget()
              
            Case #canvas
              
              Select EventType() 
                  
                Case #PB_EventType_MouseWheel
                  
                  
                  If delta >= 10
                    d=delta+(GetGadgetAttribute(#canvas,#PB_Canvas_WheelDelta )*10) ; delta*10
                    If d > 10
                      Zoom = d
                      delta = d
                    Else
                      delta=delta+(GetGadgetAttribute(#canvas,#PB_Canvas_WheelDelta )) 
                      Zoom = delta                      
                    EndIf
                    UpdateCanvas()
                  Else
                    d=delta+(GetGadgetAttribute(#canvas,#PB_Canvas_WheelDelta )*1) ; delta*10
                    If d > 0
                      delta = d
                      Zoom = delta
                      w1 = w*zoom*0.1
                      h1 = h*zoom*0.1
                      If w1 > w
                        w1 =w
                      EndIf
                      If h1 > h
                        h1 = h
                      EndIf                      
                      UpdateCanvas()
                    EndIf                    
                  EndIf
                  Debug zoom
                  
                  
                Case #PB_EventType_LeftButtonDown  ; choix du bouton deplacer
                  bm=#True
                  PosXm = GetGadgetAttribute(#canvas,#PB_Canvas_MouseX)-PosXm1
                  PosYm = GetGadgetAttribute(#canvas,#PB_Canvas_MouseY)-PosYm1 
                  
                Case #PB_EventType_MouseMove       ; deplacement
                  If bm=#True 
                    If space= 1
                      PosXm1 = GetGadgetAttribute(#canvas,#PB_Canvas_MouseX)-PosXm
                      PosYm1 = GetGadgetAttribute(#canvas,#PB_Canvas_MouseY)-PosYm
                      ;x1 = PosXm1 ;+(delta/2)
                      ;y1 = PosYm1 ;+(delta/2)                     
                      ;UpdateCanvas()
                    Else
                    EndIf
                  
                  EndIf
                  
                  
                Case #PB_EventType_LeftButtonUp                 
;                   If bm = #True
;                     bm=#False 
;                     If delta > 0
;                       x1 = PosXm1 - PosXm
;                       If x1 < 0
;                         x1 = 0
;                       EndIf                      
;                       y1 = PosYm1 - PosYm
;                       If y1 < 0 
;                         y1 = 0
;                       EndIf
;                       ratio.d = ImageHeight(#Image0)/ImageWidth(#Image0)
;                       w1 = ImageWidth(#Image0)-delta                      
;                       h1 = ImageHeight(#Image0)-delta*ratio                     
;                       UpdateCanvas()
;                     EndIf
;                   EndIf
                  
                  
                Case #PB_EventType_KeyUp
                  space = 0
                  
                  
                Case #PB_EventType_KeyDown      ; deplacement
                  key = GetGadgetAttribute(#canvas,#PB_Canvas_Key)
                  If key = 32 ; space
                    space= 1
                  EndIf
                  
                  
              EndSelect 
              
          EndSelect
          
        Case #PB_Event_SizeWindow
          
          ResizeGadget(#Scroll,#PB_Ignore,#PB_Ignore,WindowWidth(#Window),WindowHeight(#Window))
          win_w=WindowWidth(#Window)
          win_h=WindowHeight(#Window)
          
      EndSelect 
      
    Until Event= #PB_Event_CloseWindow
    End
    
  EndIf
    
EndIf
EDIT : j'ai corrigé, je m'étais trompé de version pour le code ^^