[Resolu] Pivoter une image de son point central

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

[Resolu] Pivoter une image de son point central

Message par Ulix »

Bonjour a tous (enfin ce qui voudrons bien me lire).

Je recherche du code (ou une procédure déjà toute faite, se serai le pied) pour pivoter une image.

Je désire pouvoir lui donne comme argument l'ID de limage et son degrés de rotation.

Détail important, il faut que l'image pivote autour de son point central.

J'ai trouvé un exemple fait par notre excellant ami Dobro, mais hélas l'image pivote a partir de l'angle supérieure gauche, alors que je désire la faire pivoté depuis son point central.

J'ai bien essayé de modifier le code, mais sans le résultat attendu :oops:

Si quelqu'un a un petit bout de code, merci d'avance !
Dernière modification par Ulix le ven. 06/juil./2007 18:03, modifié 1 fois.
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Dr. Dri avait fait quelque chose en DarkBasic. Je sais pas s'il a encore le code... Mais c'est assez vieux donc ca risque d'être dur à retrouver, sauf s'il a encore els fichiers sur son DD...

Je vais tenter de te retrouver ça sauf si quelqu'un t'apporte une réponse toute faite...

Lio :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

si tu cherche sur le forum anglais "rotate image" tu devrais trouver un topic qui en parle... mais bon c'est pour les fonctions les plus rapide du windows Only et c'est trop lent pour une rotation a chaque rafraichissement...Ou alors avec des tout petit sprite.
Si jamais tu trouves une fonction qui fait ça super rapidement genre une image en 800x600 rotation a 90° suffisamment rapidement pour le faire a chaque rafraichissement du screen fait moi signe je suis intéressé !! :P
minirop
Messages : 321
Inscription : mer. 02/août/2006 21:06

Message par minirop »

Thyphoon a écrit :Si jamais tu trouves une fonction qui fait ça super rapidement genre une image en 800x600 rotation a 90° suffisamment rapidement pour le faire a chaque rafraichissement du screen fait moi signe je suis intéressé !! :P
y'a peux de chance (trop de données à traiter) et pourquoi pas simplement le faire au debut du prog ?
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

Message par Ulix »

@lionel_om : Merci d'avance :P

Sur le forum anglais, j'ai trouvé plusieurs post sur la rotation d'image, mais pas vraiment se que je cherche.

Voilà le post qui ma le plus inspiré :


http://www.purebasic.fr/english/viewtop ... age+rotate


Il y a plusieurs exemples :
Avec l'utilisation d'une librairie, et apparament seul des angles de 90, 180, 270 degrés sont utilisable. Pas assez souple d'enploi !

Il y a aussi un exemple avec une API (PlgBlt_). Encore des angles de 90, 180, 270 degrés. (Je préfére éviter les API)

Il y a un exemple de code de Dobro, j'ai essayé de l'adapté sans y arriver. J'ai voulu changé les coordonnées, pour obtenir une rotation a partir du centre de l'image. Pas réussi. :oops: (Pourtant utiliser sur un tableau me plait assez)

Enfin je travail sur le code ci-dessous, l'angle ne va pas, j'ai réguliérement des "invalid memory".

Code : Tout sélectionner



Enumeration 
#f1
#Image
#GadgetImage
EndEnumeration



Procedure.f MinF(n1.f,n2.f)
  If n1<n2:ProcedureReturn n1:EndIf:ProcedureReturn n2
EndProcedure

Procedure.f MaxF(n1.f,n2.f)
  If n1>n2:ProcedureReturn n1:EndIf:ProcedureReturn n2
EndProcedure

Procedure Rotation(Image.l, Angle.l)

;code By Psychophanta in 2007-06-21 
;srcfile$="tigre.bmp"
;angle.f=#PI/6;        30° for example
;destfile$="destination.bmp"
;Source Bitmap:
;srcNumber.l=LoadImage(#PB_Any,srcfile$);,#PB_Image_DisplayFormat)
srcNumber.l=ImageID(Image)
srcWidth.l=ImageWidth(Image); <- get the length of a row of the image (in pixels)
srcHeight.l=ImageHeight(Image); <- get the length of a column of the image (in pixels)
srcDepth.l=ImageDepth(Image); <- get the length of a pixel of the image (in bits)

cosine.f=Cos(angle)
sine.f=Sin(angle)

Point1x.f=-srcHeight*sine
Point1y.f=srcHeight*cosine
Point3x.f=srcWidth*cosine
Point3y.f=srcWidth*sine
Point2x.f=Point1x+Point3x
Point2y.f=Point1y+Point3y

minx.f=MinF(0,MinF(Point1x,MinF(Point2x,Point3x)))
miny.f=MinF(0,MinF(Point1y,MinF(Point2y,Point3y)))
maxx.f=MaxF(0,MaxF(Point1x,MaxF(Point2x,Point3x)))
maxy.f=MaxF(0,MaxF(Point1y,MaxF(Point2y,Point3y)))
destWidth.l=Round(maxx-minx,1)
destHeight.l=Round(maxy-miny,1)
destDepth.l=srcDepth
;Destination bitmap:
destNumber.l=CreateImage(#PB_Any,destWidth,destHeight,destDepth)

;create DIB For SrcBitmap:
*srcBmpi.BITMAPINFO=AllocateMemory(SizeOf(BITMAPINFO)):ZeroMemory_(*srcBmpi,SizeOf(BITMAPINFO))
;init BitmapInfo struct:
*srcBmpi\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
*srcBmpi\bmiHeader\biWidth=srcWidth
*srcBmpi\bmiHeader\biHeight=srcHeight
*srcBmpi\bmiHeader\biPlanes=1
*srcBmpi\bmiHeader\biCompression=#BI_RGB
If srcDepth=24 Or srcDepth=32:*srcBmpi\bmiHeader\biBitCount=srcDepth:EndIf

;Each row is zero padded so that the number of bytes per row is divisible by 4
srcNumberOfBytesPerRow.l=((srcWidth**srcBmpi\bmiHeader\biBitCount+31)&~31)/8

;use screen DC For GetDIBits:
ScreenDC.l=GetDC_(#Null)

;get image size:
GetDIBits_(ScreenDC,ImageID(Image),0,*srcBmpi\bmiHeader\biHeight,#Null,*srcBmpi,#DIB_RGB_COLORS)
;If the driver didn't give the size, calculate it yourselves:
If *srcBmpi\bmiHeader\biSizeImage=0:*srcBmpi\bmiHeader\biSizeImage=srcNumberOfBytesPerRow*srcHeight:EndIf

;Allocate memory for the bits:
*srcbits.b=AllocateMemory(*srcBmpi\bmiHeader\biSizeImage)

;get the bits:
GetDIBits_(ScreenDC,ImageID(Image),0,*srcBmpi\bmiHeader\biHeight,*srcbits,*srcBmpi,#DIB_RGB_COLORS)

;create DIB for DestBitmap:
*destBmpi.BITMAPINFO=AllocateMemory(SizeOf(BITMAPINFO)):ZeroMemory_(*destBmpi,SizeOf(BITMAPINFO))

;init BitmapInfo struct:
*destBmpi\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
*destBmpi\bmiHeader\biWidth=destWidth
*destBmpi\bmiHeader\biHeight=destHeight
*destBmpi\bmiHeader\biPlanes=1
*destBmpi\bmiHeader\biCompression=#BI_RGB
*destBmpi\bmiHeader\biBitCount=*srcBmpi\bmiHeader\biBitCount
;Each row is zero padded so that the number of bytes per row is divisible by 4:
destNumberOfBytesPerRow.l=((destWidth**destBmpi\bmiHeader\biBitCount+31)&~31)/8

;get image size:
GetDIBits_(ScreenDC,ImageID(destNumber),0,*destBmpi\bmiHeader\biHeight,#Null,*destBmpi,#DIB_RGB_COLORS)
;If the driver didn't give the size, calculate it ourselves:
If *destBmpi\bmiHeader\biSizeImage=0:*destBmpi\bmiHeader\biSizeImage=destNumberOfBytesPerRow*destHeight:EndIf

;Allocate memory for the bits:
*destbits.b=AllocateMemory(*destBmpi\bmiHeader\biSizeImage)

;Set bits in destination buffer (perform the rotation):
For y.l=0 To destHeight
  For x.l=0 To destWidth
    SrcBitmapx.l=(x+minx)*cosine+(y+miny)*sine
    SrcBitmapy.l=(y+miny)*cosine-(x+minx)*sine
    If SrcBitmapx>=0 And SrcBitmapx<srcWidth And SrcBitmapy>=0 And SrcBitmapy<srcHeight
      CopyMemory(*srcbits+SrcNumberOfBytesPerRow*SrcBitmapy+SrcBitmapx**srcBmpi\bmiHeader\biBitCount/8+i,*destbits+DestNumberOfBytesPerRow*y+x**srcBmpi\bmiHeader\biBitCount/8+i,*srcBmpi\bmiHeader\biBitCount/8)
    EndIf
  Next
Next

;Set the bits in destination bitmap:
SetDIBits_(ScreenDC,ImageID(destNumber),0,*destBmpi\bmiHeader\biHeight,*destbits,*destBmpi,#DIB_RGB_COLORS)
;SaveImage(destNumber.l,destfile$,#PB_ImagePlugin_BMP) 

ProcedureReturn destNumber
EndProcedure




;============================================================================================================================

;Programme de test de Rotation d'une image
LoadImage(#Image, "tigre.bmp")		;chargement d'une image BMP
ResizeImage(#Image, 400, 300)		;pas trop grande, sinon resize

If OpenWindow(#f1, 0 ,0, 800, 600, "", #PB_Window_ScreenCentered| #PB_Window_SystemMenu   );
CreateGadgetList(WindowID(#f1))
ImageGadget(#GadgetImage, 0 ,0, 800, 600, ImageID(#Image))
 CreatePopupMenu(0)
 MenuItem(0, "Close")
 MenuItem(1, "Affichage Normal")
MenuItem(2, "Aide : bouton gauche pivoter")

degres=0
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow   	:		 Break
Case #WM_RBUTTONUP
								DisplayPopupMenu(0, WindowID(#f1))

Case #PB_Event_Menu
Select EventMenu()
			Case 0				:		Break
			Case 1				:		;position
											Id.l=Rotation(#Image,0)
											SetGadgetState(#GadgetImage, ImageID(id))
EndSelect
 		
Case #WM_LBUTTONUP
											degres+1
											Id.l=Rotation(#Image,degres)
											SetGadgetState(#GadgetImage, ImageID(id))
											
EndSelect
ForEver
End
EndIf



Bref je patauge.


@Thyphoon : je ne recherche pas la vitesse, mais uniquement le résultat ! (Enfin encore faut-il qu'il y est un résultat... ne vous marrez pas comme ça ) :wink:
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

sinon, une autre solution est d'utiliser la bibliothèque windows GDIPlus.dll

sur mon ordi, la rotation se fait en temps réel avec une image d'environ 300x400.

exemple :
GdiPlus_Rotate.zip
Image
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Pour la rotation d'un angle A d'un point (x,y) autour d'un centre (x0,y0), la nouvelle position (x',y') se calcule ainsi :
x' = x0 + (x-x0)*cos(A) + (y-y0)*sin(A)
y' = y0 - (x-x0)*sin(A) + (y-y0)*cos(A)
Et il faut partir de l'image d'arrivée pour calculer les pixels, en cherchant l'antécédent dans l'image d'origine en faisant une rotation inverse, ça permet de ne pas laisser de trou dans l'image finale, car on calcule tous les pixels de l'image finale.

Ensuite pour obtenir une rotation de qualité, il faut interpoler correctement les valeurs. ça je ne sais pas encore faire, je connais les noms, j'ai jamais bossé le sujet, faut chercher des exemples sur interpolation d'ordre 2 (Bell), ou interpolation d'ordre 3. Ou plus simple l'interpolation bilinéaire, ordre 1, et encore plus simple l'interpolation au plus proche voisin, d'ordre 0.

Je viens de faire une petite recherche , j'étais curieux de voir si je trouvais des trucs sur l'interpolation, et je suis tombé sur ce post

http://www.developpez.net/forums/archiv ... 32171.html
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Code : Tout sélectionner

;Rotate image
; codé par Dobro
; en purebasic 4.60

Declare rotate_image(id,x,Y,degres)


UseJPEGImageDecoder ()
InitSprite ()

#dobro =1
#Police =1
#Sprite =1
#image1 =1
#image2 =2

Structure image
	x.l
	Y.l
EndStructure
Global Dim image.image(1)


; ***********************************
FontID = LoadFont ( #Police , "arial" , 50, #PB_Font_Bold )
EcranX = GetSystemMetrics_ ( #SM_CXSCREEN ): ;=largeur de l'ecran
EcranY = GetSystemMetrics_ ( #SM_CYSCREEN ): ;=hauteur de l'ecran
WindowID = OpenWindow (1, 0, 0, EcranX, EcranY, "hello" , #PB_Window_BorderLess |#PB_Window_ScreenCentered )

WindowID = WindowID (1)
Result = OpenWindowedScreen ( WindowID ,0,0, EcranX, EcranY, 1, 0,0)


; principe de rotation
;x1 = coordonée x du point rotationé
;Y1= coordonée y du point rotationé
; a = angle de rotation
; x1 = x * Cos(a) + Y * Sin(a);
; y1 = -x * Sin(a) + Y * Cos(a)

;NomFichier$ = OpenFileRequester("charge image (pas tros grosse !!)","*.jpg", "*.jpg",0)
NomFichier$= "logo2.jpg"

LoadImage ( #image1 , NomFichier$ ) ;<----- path of the picture



largeur = ImageWidth ( #image1 )
hauteur = ImageHeight ( #image1 )
CreateImage ( #image2 ,largeur,hauteur )
Global Dim tabl1(largeur ,hauteur)

; ******* mise en tableau de l'image **********
StartDrawing ( ImageOutput ( #image1 ) )
For Y=0 To hauteur-1
	For x=0 To largeur-1
		tabl1(x,Y)= Point (x,Y)
	Next x
Next Y
StopDrawing ()
;*****************************************************

Resultat = InitMouse ()
Repeat
	ExamineMouse ()
	Event= WindowEvent ()
	Delay (2)
	angle_degres=angle_degres+2 : If angle_degres>360:angle_degres=1: EndIf
	rotate_image( #image2 ,largeur, hauteur, angle_degres)
	
	; ****** **on affiche l'image ********
	StartDrawing ( ScreenOutput ())
	DrawImage ( ImageID ( #image2 ), 1, 1)
	StopDrawing ()
	; *******************************
	FlipBuffers (): ; affiche l'ecran
	ClearScreen ( RGB (0, 0, 0)) : ;efface l'ecran
	Event= WindowEvent ()
	;}
	
	If MouseButton (2)
		End
	EndIf
	
Until Event= #PB_Event_CloseWindow


Procedure rotate_image(id,x2,y2,degres)
	;id = id picture
	;x2=Width
	;y2=Height
	
	;degres=rotation in degres
	; *** Merci Comtois : D *********
	;x' = x0 + (x-x0)*cos(A) + (y-y0)*sin(A)
	;Y' = y0 - (x-x0)*sin(A) + (y-y0)*cos(A)
	x3=x2/2 ; le milieu x de l'image
	y3=y2/2 ; le milieu y de l'image
	StartDrawing ( ImageOutput ( id ) )
	For Y=0 To y2-1
		For x=0 To x2-1
			; ********* voici la formule de la rotation d'image *********
			image(1)\x= x3+(x-x3) * Cos (degres* #PI /180) +( Y-y3)* Sin (degres* #PI /180)
			image(1)\Y= y3-(x-x3) * Sin (degres* #PI /180) + (Y-y3)* Cos (degres* #PI /180)
			;*****************************************************
			; *** on evite que les coordonée sorte du tableau dim ****
			If image(1) \Y <0 : image(1) \Y=0 : EndIf
			If image(1)\Y>y2 : image(1) \Y =y2: EndIf
			If image(1)\x>x2 : image(1)\x=x2: EndIf
			If image(1)\x<0 : image(1)\x=0: EndIf
			; *****************************************
			Plot (x,Y,tabl1( image(1)\x,image(1)\Y)) ; on dessine l'image rotaté a l'aide du tableau de points : D
		Next x
	Next Y
	StopDrawing ()
EndProcedure


Dernière modification par Backup le sam. 17/mars/2012 12:12, modifié 6 fois.
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Ulix a écrit :@lionel_om : Merci d'avance :P
Voilà j'ai retrouvé (je crois bien) : http://www.games-creator.com/forum3/vie ... highlight=

Les memblocks sont des simples tableaux avec les 12 premières cases occupées par des informations (je ne sais plus dans quel ordre) :
* largeur
* hauteur
* profondeur

Les signes # appliqu"s aux variables signifient que les variables sont de type Float (réels) !

Mais je vais te recommenter un peu son code (c'était période où il ne mettait pas une ligen de cpommentaire !!! :P ) :

Code : Tout sélectionner

`=======================
`=Commandes de réglages=
`=======================
If Check Display Mode(800,600,16)
   Set Display Mode 800,600,32
Else
   End
EndIf
Disable EscapeKey
Hide Mouse : Sync On : Sync Rate 0
Color BackDrop RGB(0,0,0)

`=======================
`=Commandes de démarage=
`=======================
Load Image "Image1.bmp",1
Set Current Bitmap 0
Dim coord(1)

Do
rotate_image(1,angle,2)
Cls 255*256*256
Paste Image 2,400-coord(0),300-coord(1)
Print "FPS : ",Screen FPS()
Print "Angle : ",angle
Inc angle : If angle=360 Then angle=0
Sync
Loop

' Début de la fonction
Function rotate_image(image,angle,rotated)
  Dim memblock(1) : Dim position(1) : y=0
  ' Cette boucle va permettre d'iniatialiser memblock(0) et memblock(1)
  ' ils renverront sur le numéro du MemBlock source et destination
  ' attention !!! "memblock" est un simple tableau de taille 2
  For x=1 To 255
     If MemBlock Exist(x)=0
        memblock(y)=x
        Inc y
     EndIf
    If y=2 Then x=256
  Next x
  
  ' si on a pas trouvé no deux MemBlock, on sort...
  If y<2 Then ExitFunction

  Make MemBlock From Image memblock(0),image
  angle=WrapValue(angle) ' on restrent l'angle entre 0 et 359 degrés (modulo strictement positif)
  cos_angle#=Cos(angle) : cos_90_angle#=Cos(90+angle)
  sin_angle#=Sin(angle) : sin_90_angle#=Sin(90+angle)
  
  ' définition de la nouvelle largeur, hauteur, offset_x et offset_y selon l'angle voulu
  If angle<90
     box_x#=MemBlock DWord(memblock(0),0)*cos_angle#-MemBlock DWord(memblock(0),4)*cos_90_angle#
     box_y#=MemBlock DWord(memblock(0),4)*cos_angle#-MemBlock DWord(memblock(0),0)*cos_90_angle#
     offset_x#=MemBlock DWord(memblock(0),4)*Cos(270+angle) : offset_y#=0
  EndIf
  If angle>=90 And angle<180
     box_x#=MemBlock DWord(memblock(0),0)*Cos(180+angle)-MemBlock DWord(memblock(0),4)*cos_90_angle#
     box_y#=MemBlock DWord(memblock(0),0)*sin_angle#-MemBlock DWord(memblock(0),4)*sin_90_angle#
     offset_x#=box_x# : offset_y#=MemBlock DWord(memblock(0),4)*Sin(270+angle)
  EndIf
  If angle>=180 And angle<270
     box_x#=MemBlock DWord(memblock(0),4)*cos_90_angle#-MemBlock DWord(memblock(0),0)*cos_angle#
     box_y#=0-MemBlock DWord(memblock(0),0)*sin_angle#-MemBlock DWord(memblock(0),4)*sin_90_angle#
     offset_x#=0-MemBlock DWord(memblock(0),0)*cos_angle# : offset_y#=box_y#
  EndIf
  If angle>=270
     box_x#=MemBlock DWord(memblock(0),0)*cos_angle#+MemBlock DWord(memblock(0),4)*cos_90_angle#
     box_y#=MemBlock DWord(memblock(0),4)*sin_90_angle#-MemBlock DWord(memblock(0),0)*sin_angle#
     offset_x#=0 : offset_y#=0-MemBlock DWord(memblock(0),0)*sin_angle#
  EndIf


  box_x=box_x# : box_y=box_y#
  If (box_x#-box_x)>=.5 Then Inc box_x
  If (box_y#-box_y)>=.5 Then Inc box_y
  coord(0)=box_x/2 : coord(1)=box_y/2

  ' Creation du MemBlock de sortie (le MemBlock sera concerti en image plustard). Premier paramètre le numéro, le 2ème taille de l'image en pixels + les 12 pixels d'entête
  Make MemBlock memblock(1),12 + box_x * box_y * MemBlock DWord(memblock(0),8)/8
  Write MemBlock DWord memblock(1),0,box_x ' on définie la largeur
  Write MemBlock DWord memblock(1),4,box_y ' on défini la hauteur
  Write MemBlock DWord memblock(1),8,MemBlock DWord(memblock(0),8) ' on défini l profondeur en reprenant celle de l'autre MemBlock

  ' opération s mathé mathématiques
  mem_step=MemBlock DWord(memblock(0),8)/8
  cos_90_angle#=Cos(90-angle) : sin_90_angle#=Sin(90-angle)
  For y=0 To MemBlock DWord(memblock(1),4)-1 : For x=0 To MemBlock DWord(memblock(1),0)-1
     rx#=(y-offset_y#)*cos_90_angle#+(x-offset_x#)*cos_angle#
     ry#=(y-offset_y#)*sin_90_angle#-(x-offset_x#)*sin_angle#
     rx=rx# : ry=ry#
     If (rx#-rx)>=.5 Then Inc rx
     If (ry#-ry)>=.5 Then Inc ry
     If rx>-1 And rx<MemBlock DWord(memblock(0),0) And ry>-1 And ry<MemBlock DWord(memblock(0),4)
        position(0)=12+mem_step*(ry*MemBlock DWord(memblock(0),0)+rx)
        position(1)=12+mem_step*(y*MemBlock DWord(memblock(1),0)+x)
        For octet=0 To mem_step-1
           Write MemBlock Byte memblock(1),position(1)+octet,MemBlock Byte(memblock(0),position(0)+octet)
        Next octet
     EndIf
  Next x : Next y

  'Fonctions de 3DGC qui converti la zone de données en images
  Make Image From MemBlock rotated,memblock(1)
  Delete MemBlock memblock(0)
  Delete MemBlock memblock(1)
  UnDim memblock
EndFunction
Lio
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

j'ai reedité mon code (et mis en couleur !) :D
il n'affiche desormais que l'image en cours ! :D

j'ai une dernière fois reediter, pour que le tableau se dimensionne au taille
de l'image !! c'est tout bete mais ça accelere sur les petites image ! :D
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

Message par Ulix »

@lionel_om : Encore merci d'avoir fait des recherches sur le net. J'ai trouvé cela intéressant.

@Dobro : Comme d'habitude, on reconnait les Cracks... Chapeau bas, et pourtant j'avais tenté d'adapté ton code pour faire pivoté une image autour de son point central, mais sans succès. J'y ai passé toute une journée, sans comprendre ou placé les coordonnées central de l'image dans la procedure de rotation. :oops:

Merci beaucoup pour ton aide :wink:

Juste une petite (toute petite demande) !

Comment supprimer l'effet miroir ou carousel (je ne sais pas si tu me comprendre) le fait que l'on voit un morceau d'une seconde image, sur les bords ?

En tout cas Merci encore pour ton aide Dobro, et merci aussi a les autres qui ont bien voulu me lire :wink:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Ulix a écrit :
Juste une petite (toute petite demande) !

Comment supprimer l'effet miroir ou carousel (je ne sais pas si tu me comprendre) le fait que l'on voit un morceau d'une seconde image, sur les bords ?
recupere le code coloré au dessus ! il Clip l'image !
la repetition venais de mes if-endif

avec la derniere version actuel, ça ne devrai plus le faire !! :D

en plus cette version dimensionne le tableau en respectant la taille de l'image
ce qui accelere le traitement des petites images !!
alors qu'avant c'etait forcé a 1024x768 !! meme pour des petites images...

j'ai surtout repris les consigne de Comtois pour le centrage :lol:
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

Message par Ulix »

Merci Drobo, c'est parfait !
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Rotation d'image avec lissage : Type phtoshop

Et oui, on avait fait ça :) vive nous tiens

http://www.purebasic.fr/french/viewtopi ... 7&start=75
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: [Resolu] Pivoter une image de son point central

Message par Zorro »

autre version de ma rotation d'image
vu que je bossais un peut dessus ce matin

ça moire un petit peux sur les angles different de 180,90,270 et... mais plus cours , tu meurt :)
mais par rapport a mon ancienne version , je ne clip plus l'image, elle reste complete (sauf si elle sort de l'ecran bien sur )

Code : Tout sélectionner



;Rotate image
;***********************************************
;Titre  :*rotate image
;Auteur  : Dobro
;Date  :30/09/2013
;Heure  :11:31:58
;Version Purebasic :  PureBasic 5.20 LTS (Windows - x8
;Version de l'editeur :EPB V2.46
; Libairies necessaire : Aucune 
;***********************************************
; en purebasic 5.70
Declare  rotate_image(id_destination,x2,y2,degres,array tabl1(2))
Declare.l RotateImageEx2(ImageID, Angle.f)

UseJPEGImageDecoder () :UsePNGImageDecoder()
InitSprite ()
#dobro =1
#Police =1
#Sprite =1
#image1 =1
#image2 =2

; ***********************************
FontID = LoadFont ( #Police , "arial" , 50, #PB_Font_Bold )
EcranX = GetSystemMetrics_ ( #SM_CXSCREEN )
;=largeur de l'ecran
EcranY = GetSystemMetrics_ ( #SM_CYSCREEN )
;=hauteur de l'ecran
WindowID = OpenWindow (1, 0, 0, EcranX, EcranY, "hello" , #PB_Window_BorderLess |#PB_Window_ScreenCentered )
WindowID = WindowID (1)
Result = OpenWindowedScreen ( WindowID ,0,0, EcranX, EcranY, 1, 0,0)

; principe de rotation
;x1 = coordonée x du point rotationé
;Y1= coordonée y du point rotationé
; a = angle de rotation
; x1 = x * Cos(a) + Y * Sin(a);
; y1 = -x * Sin(a) + Y * Cos(a)
im$=OpenFileRequester("open jpg","c:\","*.jpg",0)
;im$="D:\Dobro\Mes_Photos\Nouveau dossier\Sv101107.jpg"
LoadImage ( #image1 , im$ ) ;<----- path of the picture
largeur = ImageWidth(#image1)
hauteur = ImageHeight(#image1)
; 
if largeur>1024 or hauteur>768
		ResizeImage(#image1,1024,768)
		largeur = 1024
		hauteur =768
Endif
; 

CreateImage ( #image2 ,largeur*4,hauteur*4 ) ; image destination
; ******* mise en tableau de l'image **********
Dim tabl1(largeur ,hauteur )
StartDrawing ( ImageOutput ( #image1) )
		For Y=1 To hauteur-1
				For x=1 To largeur-1
						tabl1(x,Y)= Point (x,Y)
				Next x
		Next Y
StopDrawing ()
;*****************************************************

Resultat = InitMouse ()
TempsDepart = ElapsedMilliseconds()
Repeat
		ExamineMouse ()
		Event= WindowEvent ()
		Delay (2)
		angle_degres=angle_degres+10
		If angle_degres>360
				Event= #PB_Event_CloseWindow
				TempsEcoule = ElapsedMilliseconds()-TempsDepart
				break
		EndIf
		
		rotate_image(#image2,largeur, hauteur,  angle_degres,tabl1())   ; Call Rotate !
		
		; ****** **on affiche l'image ******** (Display image )
		StartDrawing ( ScreenOutput ())
				DrawImage ( ImageID ( #image2 ), 1, 1)
		StopDrawing ()
		; *******************************
		; affiche l'ecran
		FlipBuffers ()
		;efface l'ecran
		ClearScreen ( RGB (0, 0, 0)) 
		
		Event= WindowEvent ()
		;}
		If MouseButton (2)
				End
		EndIf
Until Event= #PB_Event_CloseWindow


;- **********************procedures Zone *********************************

Procedure rotate_image(id_destination,x2,y2,degres,array tabl1(2))
		; By Dobro	
		x3=x2/2 ; le milieu x de l'image
		y3=y2/2 ; le milieu y de l'image	
		StartDrawing ( ImageOutput ( id_destination ) )
				box(1,1,x2*2,y2*2,$0) ; clearimage
				For Y=1 To y2-1
						For x=1 To x2-1
								; ********* voici la formule de la rotation d'image *********
								x_arr.d= x3+(x-x3) * Cos (degres* #PI /180) +( Y-y3)* Sin (degres* #PI /180)
								Y_arr.d= y3-(x-x3) * Sin (degres* #PI /180) + (Y-y3)* Cos (degres* #PI /180)
								;*****************************************************			
								Plot (x_arr.d+(x2/2),Y_arr.d+(y2/3),tabl1( x,y)) ; on dessine l'image rotaté a l'aide du tableau de points : D
						Next x
				Next Y
		StopDrawing ()
EndProcedure
;


; 


; Epb
Répondre