It is currently Thu Apr 02, 2020 11:16 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Rotate images +/- 90 deg. using native code only
PostPosted: Thu Feb 06, 2014 10:31 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 24, 2011 12:40 am
Posts: 536
Location: Iowa, USA
I wanted to rotate an image left or right by 90 degrees.
There are other examples here on the forum that will do that but they were either too complex for my liking or not cross platform.

I have written a procedure that uses only native PureBasic code.
The code is simple and reasonably fast.
The image is rotated in place once it is copied into a square temporary image.
After rotation if the original image was not square there will be empty space either on top or along the left side of the temporary image.
GrabImage() is used to recover the relevant portion of the rotated image.

2.17.2014
edit: now supports 32 bit as well as 24 bit images.

Code:
; Rotate image +/- 90 degrees
; by BasicallyPure
; 2.18.2014
; supports 24 and 32 bit depth
; cross platform

EnableExplicit

Procedure ROTATE_90(image, dir)
   ; rotate image +/- 90 deg.
   ; 'image' is the number of the image to rotate
   ; if 'dir' <> 0 then rotate right else rotate left
   
   Protected a,b,c,e,f,h,s,w,x,y,ym,xm,tempImg,depth
   
   If IsImage(image) = 0 : ProcedureReturn 0 : EndIf
   
   StartDrawing(ImageOutput(image))
      w = OutputWidth()
      h = OutputHeight()
      f = DrawingBufferPixelFormat() & $7F
   StopDrawing()
     
      If f = #PB_PixelFormat_32Bits_RGB Or f = #PB_PixelFormat_32Bits_BGR
         depth = 32
      ElseIf f = #PB_PixelFormat_24Bits_RGB Or f = #PB_PixelFormat_24Bits_BGR
         depth = 24
      Else
         ProcedureReturn 0
      EndIf

   If w > h : s = w : Else : s = h : EndIf ; find the largest dimension
   
   tempImg = CreateImage(#PB_Any,s,s,depth) ; make a square working area
   
   StartDrawing(ImageOutput(tempImg))
      If depth = 32 : DrawingMode(#PB_2DDrawing_AllChannels) : EndIf
     
      DrawImage(ImageID(image),0,0)
     
      ym = s/2-1 ; max y loop value
      xm = s/2-(s!1&1) ; max x value, subtract 1 if 's' is even
      s-1
     
      If dir <> 0 ; rotate right
         For y = 0 To ym
            For x = 0 To xm
               e = Point(x,y)
               a = s-x : Plot(x,y,Point(y,a))
               b = s-y : Plot(y,a,Point(a,b))
               c = s-a : Plot(a,b,Point(b,c))
               Plot(b,c,e)
            Next x
         Next y
      Else ; rotate left
         For y = 0 To ym
            For x = 0 To xm
               e = Point(x,y)
               a = s-y : Plot(x,y,Point(a,x))
               b = s-x : Plot(a,x,Point(b,a))
               c = s-a : Plot(b,a,Point(c,b))
               Plot(c,b,e)
            Next x
         Next y
      EndIf
     
   StopDrawing()
   
   If dir <> 0
      GrabImage(tempImg,image,s-h+1,0,h,w) ; right
   Else
      GrabImage(tempImg,image,0,s-w+1,h,w) ; left
   EndIf
   
   FreeImage(tempImg)
   ProcedureReturn 1
EndProcedure


; Demo
UseJPEGImageDecoder() : UsePNGImageDecoder()

If OpenWindow(0,0,0,800,600,"",#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered)
   
   Define Pattern$ = "image (*.png, *.jpg, *.bmp)|*.png;*.jpg;*.bmp|image *.*|*.*"
   Define F$, T$, Path$ = GetHomeDirectory() + "My Pictures\"
   
   CompilerIf #PB_Compiler_OS = #PB_OS_Linux
      Path$ = GetHomeDirectory() + "Pictures/"
   CompilerEndIf
   
   CreateStatusBar(0,WindowID(0))
   AddStatusBarField(#PB_Ignore)
   ImageGadget(0,110,10,1,1,0)
   ButtonGadget(1,10,010,90,25,"Load Image")
   ButtonGadget(2,10,070,90,25,"Rotate Right")
   ButtonGadget(3,10,100,90,25,"Rotate left")
   ButtonGadget(4,10,150,90,25,"Quit")
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow : Break
         Case #PB_Event_Gadget
            Select EventGadget()
               Case 1 : F$ = OpenFileRequester("Select image", Path$, Pattern$, 0)
                  If F$ : LoadImage(0,F$)
                     If IsImage(0)
                        T$ = F$ + "  |  (" + ImageWidth(0)
                        T$ + " x " + ImageHeight(0) + ")"
                        StatusBarText(0, 0, T$)
                        SetGadgetState(0,ImageID(0))
                     EndIf
                  EndIf
               Case 2 : If ROTATE_90(0,1) : SetGadgetState(0,ImageID(0)) : EndIf
               Case 3 : If ROTATE_90(0,0) : SetGadgetState(0,ImageID(0)) : EndIf
               Case 4 : Break
            EndSelect
      EndSelect
   ForEver
   
EndIf

_________________
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.


Last edited by BasicallyPure on Sun Feb 23, 2014 7:20 pm, edited 7 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Thu Feb 06, 2014 11:07 pm 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1750
Location: Uttoxeter, UK
@BasicallyPure

Tried it with some scanned text documents.

Works perfectly.
Thank you for sharing. :D

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Thu Feb 06, 2014 11:55 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Oct 21, 2013 5:21 pm
Posts: 156
Location: France (Al's Nudie bar!)
Thanks! It's fast even with big images.

_________________
https://majikeyric.itch.io/


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Mon Feb 10, 2014 10:19 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4658
Location: Lyon - France
Works great, quick and very usefull
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Wed Feb 12, 2014 10:37 am 
Offline
Enthusiast
Enthusiast

Joined: Sat Sep 11, 2004 11:54 am
Posts: 532
Location: UK
Good morning,

I dug this out of my archives, it should be much faster than using Point() and Plot() which are traditionally very slow functions and not good news when used intensively to remap images.

(It does a flip as well... but the method can be modified to produce any combination of rotate +-90 and flip XY)

RichardL

Code:
; Simple image rotate by 90 degrees using direct access to
; image buffers. Should be cross platform... no API tricks.

; Define libraries
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()

SourceFile$ = "c:\temp\90DegreeClamp.jpg"
DestFile$   = "c:\temp\DestFile.jpg"

If LoadImage(1,SourceFile$) ; Load Image
  Iw = ImageWidth(1) : Ih = ImageHeight(1) ; Get image size
  Debug File$+"  W="+Str(Iw)+"  H="+Str(Ih)
 
  If StartDrawing(ImageOutput(1))
     
      ; Get information for source image
      *SBuf = DrawingBuffer()
      SPitch = DrawingBufferPitch()
      Select DrawingBufferPixelFormat() & $7FFF
        Case #PB_PixelFormat_24Bits_RGB : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (RRGGBB)
        Case #PB_PixelFormat_24Bits_BGR : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (BBGGRR)
        Case #PB_PixelFormat_32Bits_RGB : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (RRGGBB)
        Case #PB_PixelFormat_32Bits_BGR : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (BBGGRR)
        Default : MessageRequester("Sorry...","24 and 32 bit depths only")  : End
      EndSelect
    StopDrawing()
   
    ; Create new image with axes swapped and get it's info
    CreateImage(2,Ih,Iw,8*SBpp)
    If StartDrawing(ImageOutput(2))
        *DBuf = DrawingBuffer()
        DPitch = DrawingBufferPitch()
      StopDrawing()
     
      ; Copy image 1 to image 2 with rotation
      For Y = 0 To Ih - 2
        *S = *SBuf + (Y * SPitch)
        *D = *DBuf + (Y * SBpp)
        For X = 0 To Iw -1
          Pix = PeekL(*S)
          PokeL(*D,Pix)
          *D + DPitch
          *S + SBpp
        Next
      Next Y
     
    EndIf
  EndIf
 
  SaveImage(2,DestFile$)
 
  ; VERY crude demo of result
  h = Ih : If Iw>Ih : h = Iw : EndIf
  OpenWindow(1,100,100,Iw+Ih,h,"Test")
  StartDrawing(WindowOutput(1))
    DrawImage(ImageID(1),0,0)
    DrawImage(ImageID(2),Iw,0)
  StopDrawing()
 
  FreeImage(1)
  FreeImage(2)
 
  While WaitWindowEvent() <> #PB_Event_CloseWindow
  Wend   
   
EndIf


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Wed Feb 12, 2014 12:56 pm 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1750
Location: Uttoxeter, UK
@RichardL
Another nice example.

Thank you for sharing.

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Thu Feb 13, 2014 10:28 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4658
Location: Lyon - France
@RichardL
Yes !!! nice too :D
Thanks !!! 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Sat Feb 15, 2014 12:53 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Aug 08, 2010 3:32 pm
Posts: 349
Location: Manchester UK
Yummy, direct to drawbuffer :)

why is using direct access much quicker than point?

_________________
----

R Tape loading error, 0:1


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Sat Feb 15, 2014 1:09 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 24, 2011 12:40 am
Posts: 536
Location: Iowa, USA
@RichardL
Is there any way to prevent your code from doing a flip (mirror) as the rotation is the only effect I would like?

I spent quite a bit of time trying to do a counter-clockwise rotation with your code with only partial success.
After I made a better GUI that allows consecutive rotations I noticed the mirror problem with the original code.

I have modified your code to allow both CW and CCW rotation.
My testing has shown a problem with my CCW rotation on some images.
It perform the rotation ok but the colors are wrong on some images.
All of my test images have been 24 bit BGR as far as I can tell.

The code below has a variable named 'padding' that can fix the color problem
on the images that show wrong colors when rotated CCW if it set to equal 1.
On other images that do not show the wrong color problem there will be an IMA error if 'padding' is equal to 1.
I don't know how to determine when this variable needs to be set to 1.

I suspect but do not know if this is caused by the 'padding' that is mentioned in the help entry for DrawingBufferPitch().
I really don't know what is going on here so a solution escapes me.
If anyone knows what this 'padding' is and could explain it, that would be great.

After I noticed the mirror problem with the original code I decided to stop further work on this and I hope someone can provide some help.

What I do here for the CCW rotation is to set *DBuff to point to the end of the buffer, not the beginning.
Then the loop iterates backward thru the buffer.

Here is the code that I have so far. (Warning! This code is buggy)

Edit: I have solved the color problem. Now all images maintain the proper color when rotated.
Unfortunately I have discovered another problem with one particular image I have.
I have determined the problem (an IMA error) only occurs with an image that is 1024 x 768 in size.

(Warning! This code is still buggy but not as much. :shock: )
Code:
; Simple image rotate by 90 degrees using direct access to
; image buffers. Should be cross platform... no API tricks.

EnableExplicit

; Define libraries
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()

Procedure ROTATE(image, flag = 0)
   ;if flag <> 0 image rotates left else image rotates right
   
   Protected Iw, Ih, SBpp, DBpp, Depth, SPitch, DPitch, X, Y
   Protected result, padding, imgTemp, *SBuf, *DBuf, *D, *S
   
   If IsImage(image) = 0 : ProcedureReturn result : EndIf
   
   StartDrawing(ImageOutput(image))
     
      ; Get information for source image
      Iw = OutputWidth() : Ih = OutputHeight() ; Get image size
      *SBuf = DrawingBuffer()
      SPitch = DrawingBufferPitch()
      Select DrawingBufferPixelFormat() & $7FFF
         Case #PB_PixelFormat_24Bits_RGB : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (RRGGBB)
         Case #PB_PixelFormat_24Bits_BGR : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (BBGGRR)
         Case #PB_PixelFormat_32Bits_RGB : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (RRGGBB)
         Case #PB_PixelFormat_32Bits_BGR : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (BBGGRR)
         Default
            MessageRequester("Sorry...","24 and 32 bit depths only")
            StopDrawing()
            ProcedureReturn result
      EndSelect
   StopDrawing()
   
   ; Create temporary image with axes swapped and get it's info
   imgTemp = CreateImage(#PB_Any, Ih, Iw, 8*SBpp)
   
   If imgTemp
      StartDrawing(ImageOutput(imgTemp))
         *DBuf = DrawingBuffer()
         DPitch = DrawingBufferPitch()
         
         If flag ; rotate left
            ; DPitch is padded to multiples of 4 bytes.
            ; (Ih * SBpp) is the actual ammount of data per row.
            ; so the adjustment is as follows:
            padding = DPitch - (Ih * SBpp)
           
            ; set pointer to the last pixel data
            *DBuf = *DBuf + (Iw * DPitch) - (SBpp + padding)
           
            ; reverse the direction of data iteration
            DPitch = -DPitch
            DBpp = -SBpp
         Else
            DBpp = SBpp
         EndIf
         
         Iw - 1 : Ih - 1
         
         ; Copy image to imgTemp with rotation
         For Y = 0 To Ih
            ;fixes IMA error when image is 1024 x 768
            ;If y = Ih : Iw-1 : EndIf
           
            *S = *SBuf + (Y * SPitch)
            *D = *DBuf + (Y * DBpp)
            For X = 0 To Iw
               PokeL(*D, PeekL(*S))
               *D + DPitch
               *S + SBpp
            Next
         Next Y
      StopDrawing()
     
      CopyImage(imgTemp,image)
      FreeImage(imgTemp)
      result = 1
   EndIf
   
   ProcedureReturn result
EndProcedure

; demo
Define Path$ = GetHomeDirectory() + "My Pictures\"
Define Pattern$ = "image (*.png, *.jpg, *.bmp)|*.png;*.jpg;*.bmp|image *.*|*.*"
Define F$

OpenWindow(0, 0, 0, 910, 610, "Test",#PB_Window_MaximizeGadget)
CreateImage(1,800,600,24)
ImageGadget(0,100,5,800,600,ImageID(1))
ButtonGadget(1,5,5,90,25,"Load")
ButtonGadget(2,5,35,90,25,"Right")
ButtonGadget(3,5,65,90,25,"Left")
ButtonGadget(4,5,95,90,25,"Quit")

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_Gadget
         Select EventGadget()
            Case 1 : F$ = OpenFileRequester("Select image", Path$, Pattern$, 0)
               If F$ : LoadImage(1,F$)
                  If IsImage(1) : SetGadgetState(0,ImageID(1)) : EndIf
               EndIf
            Case 2 : ROTATE(1,0) : SetGadgetState(0,ImageID(1))
            Case 3 : ROTATE(1,1) : SetGadgetState(0,ImageID(1))
            Case 4 : Break
         EndSelect
   EndSelect
ForEver

_________________
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.


Last edited by BasicallyPure on Sun Feb 16, 2014 2:22 am, edited 2 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Sat Feb 15, 2014 7:46 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3606
Location: Netherlands
You might be careful with this latest approach.
As far as I know there's no guarantee the returned value from DrawingBuffer() is still valid after StopDrawing() is called.
It seems to work fine but in theory it's possible to have only a temporary buffer that is not accessible anymore after StopDrawing().
If the return value from DrawingBuffer() is guaranteed to be available even after StopDrawing() is called, it would be nice if Fred could add that to the documentation since it would be a nice feature.

_________________
macOS 10.15 Catalina, PB 5.71 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Sat Feb 15, 2014 9:26 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 24, 2011 12:40 am
Posts: 536
Location: Iowa, USA
You make a good point.

Thanks,
BP

_________________
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Tue Feb 18, 2014 1:01 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Mar 24, 2011 12:40 am
Posts: 536
Location: Iowa, USA
The code from the first post has been updated to support 32 bit as well as 24 bit images.

I now have fixed all of the known problems with the direct buffer access method.
Keep in mind Wilbert's warning as stated above.
Now that I have two different working methods I performed some speed test comparisons.

The code from the first post I will refer to as method 1.
The code in this post I will refer to as method 2.

Here are the results using a 24 bit test image of dimensions 3008 x 2000.
all times are in milliseconds. Each rotation was perform 4 times then averaged.

Method 1 : uses Plot() and Point() to move pixels around.
rotate right, 330, 333, 340, 344, average = 337
rotate left, 329, 333, 332, 337, average = 333

Method 2: uses Poke() and Peek() with direct buffer access.
rotate right, 233, 234, 241, 236, average = 236
rotate left, 228, 229, 233, 237, average 232

Method 2 is about 30% faster.

This has been tested with Windows and Linux.
Code:
; rotate image by 90 degrees using direct access to image buffers.
; Should be cross platform... no API tricks.
; 2.17.2014
; PureBasic 5.21
; supports 24 and 32 bit images

EnableExplicit

Procedure ROTATE(image, flag)
   ;if flag <> 0 image rotates left else image rotates right
   
   Protected A, B, result, padding, imgTemp, format
   Protected *SBuf  ; pointer to first memory byte of source buffer
   Protected *DBuf  ; pointer to first memory byte of destination buffer
   Protected *FPix  ; points to where first pixel is peeked in source buffer
   Protected *S,*D  ; source and destination pointers
   Protected Iw     ; image width
   Protected Ih     ; image height
   Protected Depth  ; image color depth, 24 or 32
   Protected SBpp   ; SourceBytesPerPixel
   Protected DBpp   ; DestinationBytesPerPixel
   Protected SPitch ; source image number of bytes per row (x)
   Protected DPitch ; destination image number of bytes per row (x)
   
   Macro Copy3Bytes(Source, Destination)
      PokeA(Destination, PeekA(Source))
      PokeW(Destination+1, PeekW(Source+1))
   EndMacro
   
   Macro Copy4Bytes(Source, Destination)
      PokeL(Destination, PeekL(Source))
   EndMacro
   
   If IsImage(image) = 0 : ProcedureReturn result : EndIf
   
   StartDrawing(ImageOutput(image))
      ; Get information for source image
      Iw = OutputWidth() : Ih = OutputHeight() ; Get image size
      *SBuf  = DrawingBuffer()
      SPitch = DrawingBufferPitch()
      format = DrawingBufferPixelFormat()
     
      Select  format & $7FFF
         Case #PB_PixelFormat_24Bits_RGB : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (RRGGBB)
         Case #PB_PixelFormat_24Bits_BGR : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (BBGGRR)
         Case #PB_PixelFormat_32Bits_RGB : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (RRGGBB)
         Case #PB_PixelFormat_32Bits_BGR : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (BBGGRR)
         Default
            MessageRequester("Sorry...","24 and 32 bit depths only")
            StopDrawing()
            ProcedureReturn result
      EndSelect
     
      If format & #PB_PixelFormat_ReversedY = 0 ; this is for Linux
         flag = flag ! 1 & 1
      EndIf
   StopDrawing()
   
   ; Create temporary image with axis swapped
   Swap Ih,Iw
   imgTemp = CreateImage(#PB_Any, Iw, Ih, 8*SBpp)
   
   ; perform the rotation
   If imgTemp
      StartDrawing(ImageOutput(imgTemp))
         *DBuf = DrawingBuffer()
         DPitch = DrawingBufferPitch()
         DBpp = SBpp
         
         If flag = 0 ; configure to rotate right
            *FPix = *SBuf + (Ih-1) * SBpp ; point to last pixel in first row
            SBpp = -SBpp ; reverse X iteration direction
         Else ; configure to rotate left
            *FPix = *SBuf + (Iw-1) * SPitch ; point to first pixel in last row
            SPitch = -SPitch ; reverse Y iteration direction
         EndIf
         
         ; time to fly
         If Depth = 24
            A = 0 : While A < Ih
               *S = *FPix + (A * SBpp)   ; set source pointer X position
               *D = *DBuf + (A * DPitch) ; set destination pointer Y position
               B = 0 : While B < Iw
                  Copy3Bytes(*S, *D)
                  *S + SPitch ; increment source pointer Y position
                  *D + DBpp   ; increment destination pointer X position
               B + 1 : Wend
            A + 1 : Wend
         ElseIf Depth = 32
            A = 0 : While A < Ih
               *S = *FPix + (A * SBpp)   ; set source pointer X position
               *D = *DBuf + (A * DPitch) ; set destination pointer Y position
               B = 0 : While B < Iw
                  Copy4Bytes(*S, *D)
                  *S + SPitch ; increment source pointer Y position
                  *D + DBpp   ; increment destination pointer X position
               B + 1 : Wend
            A + 1 : Wend
         EndIf
     
      StopDrawing()
     
      CopyImage(imgTemp,image)
      FreeImage(imgTemp)
      result = 1
   EndIf
   
   ProcedureReturn result
EndProcedure

; demo
UseJPEGImageDecoder()
UsePNGImageDecoder()

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
   Define Path$ = GetHomeDirectory() + "Pictures/"
CompilerElse
   Define Path$ = GetHomeDirectory() + "My Pictures\"
CompilerEndIf

Define Pattern$ = "image (*.png, *.jpg, *.bmp)|*.png;*.jpg;*.bmp|image *.*|*.*"
Define flags = #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered
Define F$

OpenWindow(0, 0, 0, 910, 610, "Test", flags)
SetWindowColor(0,$A0A0A0)
CreateImage(1,800,600,24)
ImageGadget(0,100,5,800,600,ImageID(1))
ButtonGadget(1,5,5,90,25,"Load")
ButtonGadget(2,5,60,90,25,"Right")
ButtonGadget(3,5,90,90,25,"Left")
ButtonGadget(4,5,145,90,25,"Quit")

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_Gadget
         Select EventGadget()
            Case 1 : F$ = OpenFileRequester("Select image", Path$, Pattern$, 0)
               If F$ : LoadImage(1,F$)
                  If IsImage(1) : SetGadgetState(0,ImageID(1)) : EndIf
               EndIf
            Case 2 : ROTATE(1,0) : SetGadgetState(0,ImageID(1))
            Case 3 : ROTATE(1,1) : SetGadgetState(0,ImageID(1))
            Case 4 : Break
         EndSelect
   EndSelect
ForEver

_________________
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Tue Feb 18, 2014 9:49 am 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1750
Location: Uttoxeter, UK
@BasicallyPure

Looks great. Some very nice improvements.

Rotating images used to be a pain. It has just got very much easier.

Thank you for sharing. :D :D

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotate images +/- 90 deg. using native code only
PostPosted: Wed Feb 19, 2014 12:54 am 
Offline
Addict
Addict
User avatar

Joined: Mon May 14, 2007 2:13 am
Posts: 979
Location: Darling River
Very nice BP, thanks for sharing. :)

_________________
PureBasic Rocks! Even More! And More!
PureBasic 5, Now We're Really Rockin!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye