PureBasic

Forums PureBasic
Nous sommes le Dim 22/Sep/2019 19:31

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 3 messages ] 
Auteur Message
 Sujet du message: 9 Patch
MessagePosté: Mar 21/Aoû/2018 17:19 
Hors ligne

Inscription: Jeu 07/Juin/2007 22:54
Messages: 261
Je n'en ai pas trouvé sur les forums PB, si ça peut servir (bien qu'il soit très basic, mais répond à mes besoins du moment...)
Code:
;Original code by Papala
;Modifications by Demivec to correct bug of unfreed temp images. Also did some code formatting for improved readability.

DeclareModule patch
  Enumeration 1
    #Patch_Copy     ;Repeat the sprite to the size
    #Patch_Stretch  ;Stretch the sprite to the size
  EndEnumeration

  Declare Image(Image, OutputWidth, OutputHeight, Corner, Flag = #Patch_Stretch) ;The imageID to 9Patch, Width & Height to reach, Corner width/height of the 9patch, Flag can be #9Patch_Copy or #9Patch_Stretch
  Declare Sprite(Image, OutputWidth, OutputHeight, Corner, Flag = #Patch_Stretch)
EndDeclareModule

Module patch
  EnableExplicit

  Structure Patch
    Sprite.i
    OutputWidth.i
    OutputHeight.i
    Corner.i
    Corner2x.i
    Horizontal.i
    Vertical.i
  EndStructure
   
  Enumeration
    #OutputType_Image  ;create a new image for output
    #OutputType_Sprite ;create a new sprite for output
  EndEnumeration

  Procedure DrawCorner(SourceImage, *data.patch)
    Protected TempImage
    ;Draw the 4 corners of the original image with no modification
    ;Top left
    TempImage = GrabImage(SourceImage, #PB_Any, 0, 0, *data\Corner, *data\Corner)
    DrawImage(ImageID(TempImage), 0, 0):
    FreeImage(TempImage)
    ;Top right
    TempImage = GrabImage(SourceImage, #PB_Any, ImageWidth(SourceImage) - *data\Corner, 0, *data\Corner, *data\Corner)
    DrawImage(ImageID(TempImage), *data\OutputWidth - *data\Corner, 0)
    FreeImage(TempImage)
    ;Bottom left
    TempImage = GrabImage(SourceImage, #PB_Any, 0, ImageHeight(SourceImage) - *data\Corner, *data\Corner, *data\Corner)
    DrawImage(ImageID(TempImage), 0, *data\OutputHeight - *data\Corner)
    FreeImage(TempImage)
    ;Bottom right
    TempImage = GrabImage(SourceImage, #PB_Any, ImageWidth(SourceImage) - *data\Corner, ImageHeight(SourceImage) - *data\Corner, *data\Corner, *data\Corner)
    DrawImage(ImageID(TempImage), *data\OutputWidth - *data\Corner, *data\OutputHeight - *data\Corner)
    FreeImage(TempImage)
  EndProcedure

  Procedure Create(SourceImage, *data.patch, flag, Type)
    Protected HLoop, VLoop, TempImage, Width, Height, Hresult, VResult
   
    *data\Horizontal = ImageWidth(SourceImage)
    *data\Vertical = ImageHeight(SourceImage)
    Select Type
        Case #OutputType_Sprite: StartDrawing(SpriteOutput(*data\Sprite))
        Case #OutputType_Image: StartDrawing(ImageOutput(*data\Sprite))
    EndSelect
   
    DrawCorner(SourceImage, *data)
    Protected Width_NoCorners = *data\OutputWidth - *data\Corner2x,
              Height_NoCorners = *data\OutputHeight - *data\Corner2x
    Select flag
      Case #Patch_Copy ;Repeat the original image's pattern to the new Width and Height
        Width = *data\Horizontal - *data\Corner2x
        Height = *data\Vertical - *data\Corner2x
       
        Protected HLoop_max = (Width_NoCorners) / Width,
                  VLoop_max = (Height_NoCorners) / Height
        For HLoop = 0 To  HLoop_max
          For VLoop = 0 To VLoop_max
       
            Select VLoop
              Case 0 ;================================Top horizontal========================
                If HLoop <> HLoop_max
                  TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, 0, Width, *data\Corner)
                Else
                  TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, 0, Width_NoCorners - Width * HLoop, *data\Corner)
                EndIf
               
                If TempImage
                  DrawImage(ImageID(TempImage), *data\Corner + Width * HLoop, 0)
                  FreeImage(TempImage)
                EndIf
              Case VLoop_max ;=======================Bottom horizontal=========================
                Debug "???"
                If HLoop <> HLoop_max
                  TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, ImageHeight(SourceImage) - *data\Corner, Width, *data\Corner)
                Else
                  TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, ImageHeight(SourceImage) - *data\Corner, Width_NoCorners - Width * HLoop, *data\Corner)
                EndIf
               
                If TempImage
                  DrawImage(ImageID(TempImage), *data\Corner + Width * HLoop, *data\OutputHeight - *data\Corner)
                  FreeImage(TempImage)
                EndIf
            EndSelect
           
            Select HLoop
              Case 0 ;===================================Left vertical=================================
                If VLoop <> VLoop_max
                  TempImage = GrabImage(SourceImage, #PB_Any, 0, *data\Corner, *data\Corner, Height)
                Else
                  TempImage = GrabImage(SourceImage, #PB_Any, 0, *data\Corner, *data\Corner, Height_NoCorners - Height * VLoop)
                EndIf
               
                If TempImage
                  DrawImage(ImageID(TempImage), 0, *data\Corner + Height * VLoop)
                  FreeImage(TempImage)
                EndIf
              Case HLoop_max ;===============================right vertical=============================
                If VLoop <> VLoop_max
                  TempImage = GrabImage(SourceImage, #PB_Any, ImageWidth(SourceImage) - *data\Corner, *data\Corner, *data\Corner, Height)
                Else
                  TempImage = GrabImage(SourceImage, #PB_Any, ImageWidth(SourceImage) - *data\Corner, *data\Corner, *data\Corner, Height_NoCorners - Height * VLoop)
                EndIf
               
                If TempImage
                  DrawImage(ImageID(TempImage), *data\OutputWidth - *data\Corner, *data\Corner + Height * VLoop)
                  FreeImage(TempImage)
                EndIf
            EndSelect
           
            ;Repeat middle's patern to fill the new image with
            If HLoop <> HLoop_max
              Hresult = Width
            Else
              Hresult = Width_NoCorners - Width * HLoop
            EndIf
           
            If VLoop <> VLoop_max
              VResult = Height
            Else
              VResult = Height_NoCorners - Height * VLoop
            EndIf
           
            TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, *data\Corner, Hresult, VResult)
            If TempImage
              DrawImage(ImageID(TempImage), *data\Corner + Width * HLoop, *data\Corner + Height * VLoop)
              FreeImage(TempImage)
            EndIf
           
          Next VLoop
        Next HLoop
       
      Case #Patch_Stretch ;Stretch the original image to the new Width and Height
        ;Top horizontal
        TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, 0, ImageWidth(SourceImage) - *data\Corner2x, *data\Corner)
        DrawImage(ImageID(TempImage), *data\Corner, 0, Width_NoCorners, *data\Corner)
        FreeImage(TempImage)
        ;Bottom horizontal
        TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, ImageHeight(SourceImage) - *data\Corner, ImageWidth(SourceImage) - *data\Corner2x, *data\Corner)
        DrawImage(ImageID(TempImage), *data\Corner, *data\OutputHeight - *data\Corner, Width_NoCorners, *data\Corner)
        FreeImage(TempImage)
        ;Left vertical
        TempImage = GrabImage(SourceImage, #PB_Any, 0, *data\Corner, *data\Corner, ImageHeight(SourceImage) - *data\Corner2x)
        DrawImage(ImageID(TempImage), 0, *data\Corner, *data\Corner, Height_NoCorners)
        FreeImage(TempImage)
        ;Right vertial
        TempImage = GrabImage(SourceImage, #PB_Any, ImageWidth(SourceImage) - *data\Corner, *data\Corner, *data\Corner, ImageHeight(SourceImage) - *data\Corner2x)
        DrawImage(ImageID(TempImage), *data\OutputWidth - *data\Corner, *data\Corner, *data\Corner, Height_NoCorners)
        FreeImage(TempImage)
        ;Middle
        TempImage = GrabImage(SourceImage, #PB_Any, *data\Corner, *data\Corner, ImageWidth(SourceImage) - *data\Corner2x, ImageHeight(SourceImage) - *data\Corner2x)
        DrawImage(ImageID(TempImage), *data\Corner, *data\Corner, Width_NoCorners, Height_NoCorners)
        FreeImage(TempImage)
    EndSelect
    StopDrawing()
  EndProcedure
   
  Procedure Image(SourceImage, OutputWidth, OutputHeight, Corner, Flag = #Patch_Stretch)
    Protected Patch.patch
    Patch\OutputWidth = OutputWidth: Patch\OutputHeight = OutputHeight: Patch\Corner = Corner: Patch\Corner2x = Corner * 2
    Patch\Sprite = CreateImage(#PB_Any, OutputWidth, OutputHeight)
    If Patch\Sprite
      Create(SourceImage, @Patch, Flag, #OutputType_Image)
      ProcedureReturn Patch\Sprite
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure

  Procedure Sprite(SourceImage, OutputWidth, OutputHeight, Corner, Flag = #Patch_Stretch)
    Protected Patch.patch
    Patch\OutputWidth = OutputWidth: Patch\OutputHeight = OutputHeight: Patch\Corner = Corner: Patch\Corner2x = Corner * 2
    Patch\Sprite = CreateSprite(#PB_Any, OutputWidth, OutputHeight, #PB_Sprite_AlphaBlending)
    If Patch\Sprite
      Create(SourceImage, @Patch, Flag, #OutputType_Sprite)
      ProcedureReturn Patch\Sprite
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
EndModule

CompilerIf #PB_Compiler_IsMainFile
  InitSprite()

  Define Image1,  Image2, Sprite1, Sprite2

  Image1 = CreateImage(#PB_Any, 20, 20)
  StartDrawing(ImageOutput(Image1))
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(0, 0, 19, 19, $FF0000)
  Circle(9, 9, 5, $FFFF00)
  Line(4, 1, 6, 1, $00FF00)
  Line(10, 1, 6, 1, $0000FF)
  StopDrawing()

  OpenWindow(0, 0, 0, 100, 200, "9 Patch Sample", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  OpenWindowedScreen(WindowID(0), 0, 0, 100, 200)

  Image2 = patch::Image(Image1, 60, 60, 4, patch::#Patch_Copy)
  Sprite1 = patch::Sprite(Image1, 40, 40, 4)
  Sprite2 = patch::Sprite(Image1, 80, 30, 4, patch::#Patch_Copy)
  StartDrawing(ScreenOutput())
  DrawImage(ImageID(Image1), 10, 0) ;Original image
  DrawImage(ImageID(Image2), 10, 30)
  StopDrawing()

  DisplaySprite(Sprite1, 10, 100)
  DisplaySprite(Sprite2, 10, 150)
  FlipBuffers()

  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
CompilerEndIf

PS : Merci Poshu de m'avoir parlé de cette techno.

Edit : Comme me l'a fait remarqué Demivec sur le forum anglais, j'oubliai de libérer les images temporaires que je créais, ce qui à long thermes pourrais être pas mal problèmatique.
@Falsam : Lui aussi trouvais que le code manquait un peut d'air, j'spère que cet édit te plairas ! :twisted:


Dernière édition par boby le Mer 22/Aoû/2018 8:32, édité 2 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: 9 Patch
MessagePosté: Mar 21/Aoû/2018 17:43 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6849
Localisation: IDF (Yvelines)
Merci Boby pour ce code qui me fait comprendre la technique du 9-patch.

Un plaisir de faire F5 et tout fonctionne.
Le module est pas mal mais le code de test et moche.
Le principal est que ce soit fonctionnel n'est ce pas ? :mrgreen:

_________________

➽ Config PureBasic : i3, RAM 4Go, NVidia (1024 Mo), Windows 10 - PB 5.70 LTS
➽ Je papote aussi sur http://purebasic.chat

➽ Sites personnels http://falsam.com & EasySprite.js

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: 9 Patch
MessagePosté: Mar 28/Aoû/2018 21:08 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 14/Oct/2004 19:48
Messages: 1121
Merci de m'avoir appris que cette technique avait un nom. Je le faisais sans jamais m'etre posé la question ...

_________________
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 5.45LTS - 32 bits


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 3 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye