Page 1 of 1

Fast Rotate /Mirror Image Effect

Posted: Thu May 07, 2020 12:40 pm
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

Re: Fast Rotate /Mirror Image Effect

Posted: Thu May 07, 2020 5:19 pm
by mk-soft
Use Vector Drawing and FlipCoordinates, RotateCoordinates ... :wink:

Re: Fast Rotate /Mirror Image Effect

Posted: Thu May 07, 2020 7:29 pm
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 ! :?

Re: Fast Rotate /Mirror Image Effect

Posted: Thu May 07, 2020 7:51 pm
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

Re: Fast Rotate /Mirror Image Effect

Posted: Thu May 07, 2020 8:02 pm
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:

Re: Fast Rotate /Mirror Image Effect

Posted: Tue Jun 16, 2020 3:25 am
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

Re: Fast Rotate /Mirror Image Effect

Posted: Tue Jun 16, 2020 7:02 am
by thyphoon
thanks for this information :D