Rotate Image
Rotate Image
I need to be able to rotate an image by 90° clockwise and anti-clockwise. It is for a picture viewer for occasions when the picture was taken with the camera rotated.
I fully expected to find this was a command in PB4 but apparently not! I have done a search, but all I have found is a library that dates back a couple of years and produces linker errors.
I feel sure someone must have done this, any pointers to where would be appreciated.
I fully expected to find this was a command in PB4 but apparently not! I have done a search, but all I have found is a library that dates back a couple of years and produces linker errors.
I feel sure someone must have done this, any pointers to where would be appreciated.
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
I have written a routine for doing this,
It works but is a bit slow, what it needs is writing in ASM or using API or both. If anyone knows how, it would be a help to have a routine to rotate the other way as well.
With my PB method the other way is just a case of starting top right and going down instead of bottom left and going up, with the columns going R>L instead of L>R.
At the moment I am about to write the clockwise bit and put them in the program, it will do until/if something faster comes up!
Code: Select all
LoadImage(0,piccy$)
x = ImageWidth(0)
y = ImageHeight(0)
Dim spotty.l(x,y)
If OpenWindow(0,0,0,x,y,"Original")
If CreateGadgetList(WindowID(0))
ImageGadget(0,0,0,x,y,ImageID(0))
EndIf
EndIf
CreateImage(1,y,x)
;
StartDrawing(ImageOutput(0))
For column = 0 To y-1
For strip = 0 To x-1
spotty(strip,column) = Point(strip,column)
Next
Next
StopDrawing()
;
StartDrawing(ImageOutput(1))
For column = 0 To y-1
For strip = 0 To x-1
Plot(column,x-strip,spotty(strip,column))
Next
Next
StopDrawing()
;
If OpenWindow(1,x+10,0,y,x,"copy")
If CreateGadgetList(WindowID(1))
ImageGadget(1,0,0,y,x,ImageID(1))
EndIf
EndIf
Repeat
ev = WaitWindowEvent()
Until ev = #PB_Event_CloseWindow
With my PB method the other way is just a case of starting top right and going down instead of bottom left and going up, with the columns going R>L instead of L>R.
At the moment I am about to write the clockwise bit and put them in the program, it will do until/if something faster comes up!
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
I made a lib for that very purpose a while back. It's coded in API and will be quite a bit faster than what you've got there. You are welcome to use it. It has one command, you call it like this:
where the last parameter is 1=90 degrees clockwise, 2=180 degrees, 3=90 degrees counterclockwise. If it succeeds, the dll returns an image handle with the rotated image, if it fails the return value is 0. You must pass 1, 2, or 3 as rotation parameters, anything else returns failed.
As a new image is created each time you call the function, you must remember to:
when you're finished with it or you'll have a memory leak.
http://www.networkmaestro.com/Quarters.dll
Code: Select all
OpenLibrary(0,"Quarters.dll")
MyImage = CallFunction(0,"TurnByQuarters",ImageID(#image), 1)
CloseLibrary(0)
As a new image is created each time you call the function, you must remember to:
Code: Select all
DeleteObject_(MyImage)
http://www.networkmaestro.com/Quarters.dll
Having to carry along extra DLL's with your app is such a pain 
Here is some code I threw together...

Here is some code I threw together...
Code: Select all
; Image Rotating Code
; by Paul Leischow
; Compiler: PB 3.94
Procedure Image_Rotate(Image.l)
height=ImageHeight()
width=ImageWidth()
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())
DrawImage(UseImage(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,UseImage(1))
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
EndIf
and for those who still have problems converting to PB 4.00 ....
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
- Thorsten1867
- Addict
- Posts: 1372
- Joined: Wed Aug 24, 2005 4:02 pm
- Location: Germany
Code: Select all
Procedure RotateImg(Image$,opt.b)
hnd1.l = LoadImage(#ImageRotate1,Image$)
bitmap_w = ImageWidth(#ImageRotate1)
bitmap_h = ImageHeight(#ImageRotate1)
hnd2 = CreateImage(#ImageRotate2,bitmap_h, bitmap_w)
source_dc = CreateCompatibleDC_(main_dc) : SelectObject_(source_dc,hnd1)
dest_dc = CreateCompatibleDC_(main_dc) : SelectObject_(dest_dc,hnd2)
ia = bitmap_h
If opt = 1
While ia > 0 ;{ 90° nach rechts
i = 0
While i < bitmap_w
BitBlt_(dest_dc,bitmap_h-ia,i,1,1,source_dc,i,ia,#SRCCOPY)
i + 1
Wend
ia - 1
Wend ;}
Else
While ia > 0 ;{ 90° nach links
i = 0
While i < bitmap_w
BitBlt_(dest_dc,ia,bitmap_w-i,1,1,source_dc,i,ia,#SRCCOPY)
i + 1
Wend
ia - 1
Wend ;}
EndIf
deletedc_(source_dc)
deletedc_(dest_dc)
SaveImage(#ImageRotate2,Image$,#PB_ImagePlugin_JPEG)
EndProcedure
Translated with http://www.DeepL.com/Translator
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Thanks for the help chaps, I have tried each of the them and they all work well.
I think that the one that is best for my purpose is the one by Thorsten as I have modified it slightly to rotate an already loaded image. I also did not want to save the new (rotated) version.
I can now pass the image number and option, the procedure creates the new rotated image then copies the new one to the original and frees the new one.
I think that the one that is best for my purpose is the one by Thorsten as I have modified it slightly to rotate an already loaded image. I also did not want to save the new (rotated) version.
I can now pass the image number and option, the procedure creates the new rotated image then copies the new one to the original and frees the new one.
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
After inclusion in my program, I found a slight bug in the routines as the positions on the bitmap go from 0 to x-1 and 0 to y-1, not 1 to x and 1 to y, where x and y are the Image width and Image height. This caused a single pixel black line on the rotated image.
Corrected as follows
Added the '=' on the two occurences of 'While ia >= 0' and the -1 in the 'BitBlt_(dest_dc, bitmap_h-ia-1, i, 1, 1,source_dc, i, ia, #SRCCOPY)' and 'BitBlt_(dest_dc, ia, bitmap_w-i-1, 1, 1, source_dc, i, ia, #SRCCOPY)'
Corrected as follows
Code: Select all
If opt = 1 ; 90° clockwise
While ia >= 0
i = 0
While i < bitmap_w
BitBlt_(dest_dc, bitmap_h-ia-1, i, 1, 1,source_dc, i, ia, #SRCCOPY)
i + 1
Wend
ia - 1
Wend
Else ; 90° anticlockwise
While ia >= 0
i = 0
While i < bitmap_w
BitBlt_(dest_dc, ia, bitmap_w-i-1, 1, 1, source_dc, i, ia, #SRCCOPY)
i + 1
Wend
ia - 1
Wend
EndIf
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
-
- Enthusiast
- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
[quote="netmaestro"]I made a lib for that very purpose a while back. It's coded in API...
@netmaestro
Does this routine use PlgBLT API? I'm looking for something useable on Win32 (Win98SE).
I'm not getting a failure, just not getting an image back. A sligthly extended example would probably help me
Terry
@netmaestro
Does this routine use PlgBLT API? I'm looking for something useable on Win32 (Win98SE).
I'm not getting a failure, just not getting an image back. A sligthly extended example would probably help me

Terry
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
The code for that dll is buried on a cd somewhere, I can probably come up with it if necessary but I'm pretty sure it's going to need Win2000/XP. If I were you I'd use gdiplus.dll for this and distribute it with your app. If you need a sample (or the whole thing it's pretty short) I can post it tomorrow. I'm not sure what your non-gdiplus 9x alternatives are, but if you do it this way it'll work on W9x and go blazing fast.
BERESHEIT
-
- Enthusiast
- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Code: Select all
OpenLibrary(0,"Quarters.dll")
MyImage = CallFunction(0,"TurnByQuarters",ImageID(#image), 1)
CloseLibrary(0)
SetGadgetState(#img, MyImage)
; later when you're finished with it
DeleteObject_(MyImage)
BERESHEIT
-
- Enthusiast
- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
@netmaestro
Thanks, but I'm still failing. Here is my code, maybe you see the error.
[edited: Code now works -
]
Thanks, but I'm still failing. Here is my code, maybe you see the error.
[edited: Code now works -

Code: Select all
Pgm$ = "Image rotation test"
ExamineDesktops()
#Window=0
If OpenWindow(#Window,0,0,DesktopWidth(0),DesktopHeight(0) - 33,Pgm$,#PB_Window_SystemMenu)
CreateGadgetList(WindowID(#Window))
dc = StartDrawing(WindowOutput(0)) ; Change to the desired output
Box(0,0, WindowWidth(0), WindowHeight(0),#White) ; Set the image to background color
Image = LoadImage(#PB_Any,"\purebasic_4\purebasic.bmp")
ImageGadget(2, 0, 0,ImageWidth(Image), ImageHeight(Image), ImageID(Image)) ; show the image
ImageGadget(3, 200, 200, 200, 200, ImageID(Image)) ; show the image
While WindowEvent():Wend
Delay(2000) ; wait 2 seconds then rotate the image
If OpenLibrary(0,"Quarters.dll")
MyImage = CallFunction(0,"TurnByQuarters",ImageID(Image), 1)
SetGadgetState(3, MyImage)
While WindowEvent():Wend
DeleteObject_(MyImage)
CloseLibrary(0)
Else
MessageRequester("Debug","Could not open the library",#MB_ICONERROR)
EndIf
Repeat
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow
EndIf
End
Last edited by TerryHough on Sun Nov 26, 2006 3:07 am, edited 2 times in total.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Try this test prog:
Code: Select all
Image = LoadImage(#PB_Any,"\purebasic_4\purebasic.bmp")
OpenWindow(0,0,0,320,240,"",$CF0001)
CreateGadgetList(WindowID(0))
ImageGadget(0,50,20,0,0,ImageID(image))
ButtonGadget(1,100,210,80,20,"flip")
Repeat
ev = WaitWindowEvent()
If ev=#PB_Event_Gadget
If EventGadget()=1
OpenLibrary(0,"quarters.dll")
MyImage = CallFunction(0,"TurnByQuarters",ImageID(image),1)
SetGadgetState(0, MyImage)
CloseLibrary(0)
EndIf
EndIf
Until ev= #WM_CLOSE
If MyImage
DeleteObject_(MyImage)
EndIf
BERESHEIT
-
- Enthusiast
- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact: