Fast Rotate /Mirror Image Effect

Share your advanced PureBasic knowledge/code with the community.
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 355
Joined: Sat Dec 25, 2004 2:37 pm

Fast Rotate /Mirror Image Effect

Post by thyphoon »

Hello, I use this code but it's Windows Only.
Do you know how to do the same on Linux or MacOS ?

Code: Select all

Enumeration  1
   #Effect_Normal
   #Effect_Mirror_horizontal
   #Effect_Rotate_180
   #Effect_Mirror_vertical
   #Effect_Mirror_horizontal_Rotate_270_CW
   #Effect_Rotate_90_CW
   #Effect_Mirror_Horizontal_Rotate_90_CW
   #Effect_Rotate_270_CW
EndEnumeration

Procedure.i RotateImage(Image.i,Effect.l)

  Protected Height.l = ImageHeight(Image)
  Protected Width.l = ImageWidth(Image)
  Protected sizeMax.l
  Protected TmpImage.i
  If Height > Width
    sizeMax=Height
    Else
    sizeMax=Width
  EndIf
  TmpImage = CreateImage(#PB_Any,sizeMax,sizeMax,ImageDepth(Image))
  Dim p.point(2)
  Protected GrabWidth.l,GrabHeight.l
  Select Effect.l
    Case 0
      FreeImage(TmpImage)
      ProcedureReturn Image
    Case 1 ; Horizontal (normal)
      FreeImage(TmpImage)
      ProcedureReturn Image
    Case 2 ; Mirror horizontal
      p(0)\x=0
      p(0)\y=Height
      p(1)\x=Width
      p(1)\y=Height
      p(2)\x=0
      p(2)\y=0
      GrabWidth=Width
      GrabHeight=Height
    Case 3 ; Rotate 180
      p(0)\x=Width
      p(0)\y=Height
      p(1)\x=0
      p(1)\y=Height
      p(2)\x=Width
      p(2)\y=0
      GrabWidth=Width
      GrabHeight=Height
    Case 4 ; Mirror vertical
      p(0)\x=Width
      p(0)\y=0
      p(1)\x=0
      p(1)\y=0
      p(2)\x=Width
      p(2)\y=Height
      GrabWidth=Width
      GrabHeight=Height
    Case 5 ; Mirror horizontal And rotate 270 CW
      p(0)\x=0
      p(0)\y=0
      p(1)\x=0
      p(1)\y=Width
      p(2)\x=Height
      p(2)\y=0
      GrabWidth=Height
      GrabHeight=Width   
    Case 6 ; Rotate 90 CW
      p(0)\x=Height
      p(0)\y=0
      p(1)\x=Height
      p(1)\y=Width
      p(2)\x=0
      p(2)\y=0
      GrabWidth=Height
      GrabHeight=Width
    Case 7 ; Mirror horizontal And rotate 90 CW
      p(0)\x=0
      p(0)\y=0
      p(1)\x=0
      p(1)\y=Width
      p(2)\x=Height
      p(2)\y=0
      GrabWidth=Height
      GrabHeight=Width
    Case 8 ; Rotate 270 CW
      p(0)\x=0
      p(0)\y=Width
      p(1)\x=0
      p(1)\y=0
      p(2)\x=Height
      p(2)\y=Width
      GrabWidth=Height
      GrabHeight=Width
  EndSelect

  Protected Dc.i
  Dc = StartDrawing(ImageOutput(TmpImage))
       DrawingMode(#PB_2DDrawing_AlphaChannel)
       Box(0, 0, sizeMax, sizeMax, RGBA(0,0,255,0))
       DrawingMode(#PB_2DDrawing_AlphaBlend)
       DrawAlphaImage(ImageID(Image),0,0)
       PlgBlt_(Dc,p(),Dc,0,0,Width,Height,0,0,0)
       StopDrawing()
       FreeImage(Image)
       Protected NewImage.i
  NewImage = GrabImage(TmpImage,#PB_Any,0,0,GrabWidth,GrabHeight)
  FreeImage(TmpImage)
  ProcedureReturn NewImage
EndProcedure
User avatar
mk-soft
Always Here
Always Here
Posts: 6249
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Fast Rotate /Mirror Image Effect

Post by mk-soft »

Use Vector Drawing and FlipCoordinates, RotateCoordinates ... :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 355
Joined: Sat Dec 25, 2004 2:37 pm

Re: Fast Rotate /Mirror Image Effect

Post by thyphoon »

mk-soft wrote:Use Vector Drawing and FlipCoordinates, RotateCoordinates ... :wink:
no i can't use it because i want pixel perfect with no anti-aliasing ! :?
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Fast Rotate /Mirror Image Effect

Post by davido »

@thyphoon,
Please take a look at the code below:

https://www.purebasic.fr/english/viewto ... 74#p437174

You might also like to take a look at the following. The post is old but from an excellent source:
https://www.purebasic.fr/english/viewto ... 72#p298872
DE AA EB
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 355
Joined: Sat Dec 25, 2004 2:37 pm

Re: Fast Rotate /Mirror Image Effect

Post by thyphoon »

davido wrote:@thyphoon,
Please take a look at the code below:

https://www.purebasic.fr/english/viewto ... 74#p437174

You might also like to take a look at the following. The post is old but from an excellent source:
https://www.purebasic.fr/english/viewto ... 72#p298872
Great :D but how could I miss this? :shock:
User avatar
kenmo
Addict
Addict
Posts: 2047
Joined: Tue Dec 23, 2003 3:54 am

Re: Fast Rotate /Mirror Image Effect

Post by kenmo »

For anyone using the Windows API code above, please be aware the 180 rotation gives slightly wrong results! (Top row and Left column are not changed.)

It's not the coder's fault, or PureBasic's fault. PlgBlt_() seems to have bugs at exactly 180 degrees in any language.
http://www.vbforums.com/showthread.php? ... s-or-a-bug
https://www.gamedev.net/forums/topic/38 ... -mask-bug/
etc.
yes, that's a bug. The somewhat inelegant solution is to offset
the coordinates of
a vertex by one pixel at a rotation angle of 180 ° . This
does not create an exact rectangle and the error does
not occur.
Better yet, for 180 use StretchBlt_(), something like this. (I get pixel-perfect results.)

Code: Select all

StretchBlt_(*DC, Width-1, Height-1, -Width, -Height, *DC, 0, 0, Width, Height, #SRCCOPY)

You can see the PlgBlt_() 180 error in this example, attach it to the code far above:

Code: Select all

Size = 128
LoadFont(0, "Arial", Size/10)

CreateImage(0, Size, Size, 24, #White)
If StartDrawing(ImageOutput(0))
  Box(0, 0, Size/2, Size/2, $c0c0ff)
  Box(Size/2, 0, Size/2, Size/2, $c0ffc0)
  Box(0, Size/2, Size/2, Size/2, $c0ffff)
  Box(Size/2, Size/2, Size/2, Size/2, $ffffc0)
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawingFont(FontID(0))
  DrawText(Size/16, Size/16, "Source Image", #Black)
  StopDrawing()
EndIf

CopyImage(0, 1)
Rot90  = RotateImage(1, #Effect_Rotate_90_CW)
CopyImage(0, 1)
Rot180 = RotateImage(1, #Effect_Rotate_180)
CopyImage(0, 1)
Rot270 = RotateImage(1, #Effect_Rotate_270_CW)

Padding = 30
OpenWindow(0, 0, 0, 3 * Padding + 2 * Size, 3 * Padding + 2 * Size, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
SetWindowColor(0, #White)

ImageGadget(0, Padding, Padding, Size, Size, ImageID(0))
ImageGadget(1, Padding * 2 + Size, Padding, Size, Size, ImageID(Rot90))
ImageGadget(2, Padding, Padding * 2 + Size, Size, Size, ImageID(Rot180))
ImageGadget(3, Padding * 2 + Size, Padding * 2 + Size, Size, Size, ImageID(Rot270))

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
User avatar
thyphoon
Enthusiast
Enthusiast
Posts: 355
Joined: Sat Dec 25, 2004 2:37 pm

Re: Fast Rotate /Mirror Image Effect

Post by thyphoon »

thanks for this information :D
Post Reply