Rotate Image

Just starting out? Need help? Post your questions and find answers here.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Yes, the dll owns the object. My sample is poorly written too as it seems to work fine but if you do the flip and then move the window partly off-screen and back, the picture is gone. SOP for using image dlls is to close the library when the program closes.
BERESHEIT
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

@netmaestro
Thanks for your help.

FYI, your dll does not work with Win98SE as you suspected. To bad, as that is what I really need. Loads of users with old machines who just have no real reason to upgrade.

Also, the rotated image is not quite correct. Look closely at the results of the corrected code I posted above. You will notice a black line at the bottom of the rotated image, approximately 1-2 pixels high. The top of the image is trimmed approximately the same amount. I didn't notice it myself at first with the Purebasic.bmp, but when I rotated the images I actually planned to use it was apparent.

Here is an example of the original and rotated image.

Image
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Terry, take a look at http://www.leunen.com/cbuilder/rotbmp.html (5. Rotating bitmaps using DIBs). That code (converted to PB) works on Win98. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Thanks Sparkie, I will give it a look.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Before you go through the translation process, you can verify the code will work on your Win98 machines by using this test app I threw together. :)

The .exe size is ~415KB due to the inclusion of the 4 PB image decoders. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Criss
New User
New User
Posts: 9
Joined: Mon Dec 04, 2006 9:41 am

Post by Criss »

@Sparkie, nice Tool! Can you list here, your source, please?
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Post by dobro »

rotate image in degres

picture for test :
Image


Code: Select all





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

Declare rotate_image(id,x,Y,degres) 


UseJPEGImageDecoder ()
InitSprite ()

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

Structure image
    x.l[1024]
    Y.l[768] 
EndStructure
Global Dim image.image(360)
Global Dim tabl1(1024,768 )

; ***********************************
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) 
    
LoadImage ( #image1 , "logo2.jpg" ) ;<----- path of the picture
largeur = ImageWidth(#image1)
hauteur = ImageHeight(#image1)  
CreateImage ( #image2 ,largeur,hauteur )
    
    ; ******* mise en tableau de l'image **********
StartDrawing ( ImageOutput ( #image1 ) )
For Y=1 To hauteur
    For x=1 To largeur
        tabl1(x,Y)= Point (x,Y)  
    Next x
Next Y
StopDrawing ()
  ;*****************************************************  
    
Resultat = InitMouse ()
Repeat
    ExamineMouse ()
    Event= WindowEvent ()
    Delay (2) 
    angle_degres=angle_degres+1 :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
    StartDrawing ( ImageOutput ( id ) )
    For Y=1 To y2
        For x=1 To x2
            ; ********* voici la formule de la rotation d'image *********
            image(degres)\x[x]= x * Cos (degres* #PI /180) + Y* Sin (degres* #PI /180)
            image(degres)\Y[Y]= -x * Sin (degres* #PI /180) + Y* Cos (degres* #PI /180) 
            ;***************************************************** 
            ; *** on evite que les coordonée sorte du tableau dim ****
            If   image(degres) \Y[Y] <0 : image(degres) \Y[Y]=y2-image(degres) \Y[Y] : EndIf
            If   image(degres)\Y[Y] >y2 : image(degres) \Y[Y] =0+image(degres)\Y[Y] -y2: EndIf
            If    image(degres)\x[x]>x2 : image(degres)\x[x]=0+image(degres)\x[x]-x2: EndIf
            If    image(degres)\x[x]<1 : image(degres)\x[x]=x2-image(degres)\x[x]: EndIf  
            ; ***************************************** 
            Plot (x,Y,tabl1( image(degres)\x[x],image(degres)\Y[Y])) ; on dessine l'image rotaté a l'aide du tableau de points : D
        Next x
    Next Y 
    StopDrawing () 
EndProcedure


Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
Lna
User
User
Posts: 21
Joined: Wed Dec 06, 2006 10:49 pm
Location: France

Post by Lna »

@Sparkie :

Tested on win 98 se : OK 8)
Tested on win 2000 professional: OK 8)

And it is fast. 8)
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

For those interested i've translated the C++ Builder source at http://www.leunen.com/cbuilder/rotbmp.html (section 5. Rotating bitmaps using DIBs) to PB 4.10b2.
So then the Sparkie program source core is something like this here:

Code: Select all

;Rotate an image bitmap.
;Translated from C++Builder code from http://www.leunen.com/cbuilder/rotbmp.html (section 5. Rotating bitmaps using DIBs)
;By Psychophanta in 2007-06-21
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
srcfile$="source.bmp"
angle.f=#PI/6;        30° for example
destfile$="destination.bmp"
;Source Bitmap:
srcNumber.l=LoadImage(#PB_Any,srcfile$);,#PB_Image_DisplayFormat)
srcWidth.l=ImageWidth(srcNumber); <- get the length of a row of the image (in pixels)
srcHeight.l=ImageHeight(srcNumber); <- get the length of a column of the image (in pixels)
srcDepth.l=ImageDepth(srcNumber); <- 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(srcNumber),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(srcNumber),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)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
hth
User
User
Posts: 41
Joined: Tue Aug 21, 2007 8:01 pm

rotate image 90, 180, 270

Post by hth »

What must be change, to rotate the image in 180 and 270 grad?
(Sorry for my bad English.)

hth

Code: Select all

; Image Rotating Code 
; by Paul Leischow 
; Compiler: PB 4.00 

Procedure Image_Rotate(Image.l) 
  height=ImageHeight(Image) 
  width=ImageWidth(Image) 
  If height>width 
    temp=CreateImage(#PB_Any,height,height) 
    Else 
    temp=CreateImage(#PB_Any,width,width) 
  EndIf 
  
  Dim rect.Point(2) 
  rect(0)\x=height 
  rect(0)\y=0 
  rect(1)\x=height 
  rect(1)\y=width 
  rect(2)\x=0 
  rect(2)\y=0 
  dc=StartDrawing(ImageOutput(temp)) 
    DrawImage(ImageID(Image),0,0) 
    PlgBlt_(dc,@rect(),dc,0,0,width,height,0,0,0) 
  StopDrawing() 
  GrabImage(temp,image,0,0,height,width) 
  FreeImage(temp) 
EndProcedure 



LoadImage(1,"picture1.bmp") 
Image_Rotate(1) ;rotates image 90 degrees clockwise everytime you call procedure 

If OpenWindow(0,0,0,600,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
  If CreateGadgetList(WindowID(0)) 
    ImageGadget(0,0,0,10,10,ImageID(1)) 
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow 
  EndIf 
EndIf 
akee
Enthusiast
Enthusiast
Posts: 496
Joined: Wed Aug 18, 2004 9:52 am
Location: Penang, Malaysia

Post by akee »

3 coordinates to the destination

top-left, top-right and bottom-left

Code: Select all

; 180 degrees
;  rect(0)\x=width
;  rect(0)\y=height
;  rect(1)\x=0 
;  rect(1)\y=height
;  rect(2)\x=width
;  rect(2)\y=0

; 270 degrees
;  rect(0)\x=0
;  rect(0)\y=height 
;  rect(1)\x=0 
;  rect(1)\y=0
;  rect(2)\x=width 
;  rect(2)\y=height
pantsonhead
User
User
Posts: 39
Joined: Fri Mar 26, 2004 1:47 pm
Location: London, UK
Contact:

Post by pantsonhead »

270 degrees should be

Code: Select all

    rect(0)\x=0
    rect(0)\y=width
    rect(1)\x=0
    rect(1)\y=0
    rect(2)\x=height
    rect(2)\y=width
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Post by djes »

Why don't you just use the "search" function above?

Here's some code you'll be able to find : http://www.purebasic.fr/english/viewtop ... t=rotation
Dr Soong
User
User
Posts: 14
Joined: Tue Nov 17, 2015 11:20 pm

Re: Rotate Image Clockwise and Counter-Clockwise

Post by Dr Soong »

Paul wrote:

Code: Select all

; Image Rotating Code
; by Paul Leischow
; Compiler: PB 4.00

Procedure Image_Rotate(Image.l)
  height=ImageHeight(Image)
  width=ImageWidth(Image)
  If height>width
    temp=CreateImage(#PB_Any,height,height)
    Else
    temp=CreateImage(#PB_Any,width,width)
  EndIf
  
  Dim rect.Point(2)
  rect(0)\x=height
  rect(0)\y=0
  rect(1)\x=height
  rect(1)\y=width
  rect(2)\x=0
  rect(2)\y=0
  dc=StartDrawing(ImageOutput(temp))
    DrawImage(ImageID(Image),0,0)
    PlgBlt_(dc,@rect(),dc,0,0,width,height,0,0,0)
  StopDrawing()
  GrabImage(temp,image,0,0,height,width)
  FreeImage(temp)
EndProcedure



LoadImage(1,"picture1.bmp")
Image_Rotate(1) ;rotates image 90 degrees clockwise everytime you call procedure

If OpenWindow(0,0,0,600,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  If CreateGadgetList(WindowID(0))
    ImageGadget(0,0,0,10,10,ImageID(1))
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
  EndIf
EndIf
Paul, your original Image Rotating Code is exactly what I needed for my application. I have been able to use it for both clockwise, and simulating counter-clockwise rotation (run the clockwise code 3 times...). But I was wondering if you could suggest a more elegant solution to provide -90 degree rotation (counter-clockwise) with a single call. My PB Kung Fu is not yet strong Master...
PB: 6.00 LTS (x86) OS: Windows 10
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Rotate Image

Post by IdeasVacuum »

IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply