Page 2 of 2

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 12:37 pm
by Saki
Interesting :wink:

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 12:47 pm
by RASHAD
Hi IV
Your problem with the lost of 1 pix each side has been discussed with srod and others long time back
Using ResetPath() solved some but still some not solved
It's freak after all
So don't wait for a solution soon
It can be solved by 2D drawing and Windows API but you will loose the anti-alias of the Vector lib.
If you like so tell me

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 1:39 pm
by IdeasVacuum
Hi Rashad

I have adapted the pixel based functions by Luis:
viewtopic.php?f=12&t=38975

I am only performing orthogonal rotates, so there is no anti-aliasing to be considered.

My conclusion with the vector rotate error is that it depends on whether the image dimensions (pixels) are odd or even. The vector library code that performs the rotate could apply a move-translate to ensure the top-left image corner is at the ordinates of the original.

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 2:13 pm
by Saki
Both are not correct
It is also about the interpolation of the image edges, not the image itself.
But this is optically hardly perceptible.

There are other problems when rotating images with transparent backgrounds with Vector Lib.

But it should be good so.

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 2:34 pm
by RASHAD
The next snippet by Lord to rotate image by 90 deg Left or Right
- Ctrl-O to load image
- L to rotate left
- R to rotate right
You can handle the transparency later after rotating the image
If you need a snippet to rotate by 1 deg there is one by djes I can post it if you like
I have my own but I can not post it right now(Vector lib.)

Code: Select all

; RotateLeft90() and RotateRight90()
; Based on code by Ligatur and hjbremer
; https://www.purebasic.fr/german/viewtopic.php?f=16&t=18695
; Improved by Lord to overcome the limits for PlgBlt_()
; https://www.purebasic.fr/english/viewtopic.php?f=13&t=48002

EnableExplicit

Enumeration
  #MainWindow
EndEnumeration
Enumeration
  #ScrollArea
  #Canvas
EndEnumeration
Enumeration
  #Img1
  #Img2
  #Img3
EndEnumeration
Enumeration
  #Open
  #Left
  #Right
EndEnumeration
EnumerationBinary 128
  #BS128
  #BS256
  #BS512
  #BS1024
  #BS2048
EndEnumeration

#BlockSize=#BS512; A BlockSize of 512x512 turned out to be the fastest way to rotate a big image 

Define Event, Quit=#False

UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Procedure RotateLeft90()
  Protected iw, ih, x, y, dc
  iw=ImageWidth(#Img1):ih=ImageHeight(#Img1)
  If CreateImage(#Img2, ih, iw)
    Dim p.point(2)
    For y=0 To ih Step #BlockSize
      For x=0 To iw Step #BlockSize
        If GrabImage(#Img1, #Img3, x, y, #BlockSize, #BlockSize)
          p(0)\x=0
          p(0)\y=#BlockSize
          p(1)\x=0
          p(1)\y=0
          p(2)\x=#BlockSize
          p(2)\y=#BlockSize
          dc = StartDrawing(ImageOutput(#Img3))
            If dc
              PlgBlt_(dc, p(), dc, 0, 0, #BlockSize, #BlockSize, 0, 0, 0)
            EndIf
          StopDrawing()
          If StartDrawing(ImageOutput(#Img2))
              DrawImage(ImageID(#Img3), y, iw-x-#BlockSize)
            StopDrawing()
          EndIf
        EndIf
      Next
    Next
    CopyImage(#Img2, #Img1)
  EndIf
EndProcedure
Procedure RotateRight90()
  Protected iw, ih, x, y, dc
  iw=ImageWidth(#Img1):ih=ImageHeight(#Img1)
  If CreateImage(#Img2, ih, iw)
    Dim p.point(2)
    For y=0 To ih Step #BlockSize
      For x=0 To iw Step #BlockSize
        If GrabImage(#Img1, #Img3, x, y, #BlockSize, #BlockSize)
          p(0)\x=#BlockSize
          p(0)\y=0
          p(1)\x=#BlockSize
          p(1)\y=#BlockSize
          p(2)\x=0
          p(2)\y=0
          dc = StartDrawing(ImageOutput(#Img3))
            If dc
              PlgBlt_(dc,p(),dc,0,0,#BlockSize,#BlockSize,0,0,0)
            StopDrawing()
          EndIf
          If StartDrawing(ImageOutput(#Img2))
              DrawImage(ImageID(#Img3), ih-y-#BlockSize, x)
            StopDrawing()
          EndIf
        EndIf
      Next
    Next
    CopyImage(#Img2, #Img1)
  EndIf
EndProcedure
Procedure OpenImage()
  Protected I1W, I1H
  Protected Img.s
  Img=OpenFileRequester("SELECT IMAGE","","All supported formats|*.*;*.bmp;*.gif; *.jpg; *.jpeg;*.png;*.tif;*.tiff;*.tga|TGA image (*.tga)|*.tga|TIF image (*.tif)|*.tif|TIFF image (*.tiff)|*.tiff|PNG image (*.png)|*.png|BMP image (*.bmp)|*.bmp|JPEG image (*.jpg;*.jpeg)|*.jpg;*.jpeg|GIF image (*.gif)|*.gif",0)
  If Img
    If LoadImage(#Img1, Img)
      I1W=ImageWidth(#Img1)
      I1H=ImageHeight(#Img1)
      SetGadgetAttribute(#ScrollArea, #PB_ScrollArea_InnerWidth, I1W)
      SetGadgetAttribute(#ScrollArea, #PB_ScrollArea_InnerHeight, I1H)
      ResizeGadget(#Canvas, #PB_Ignore, #PB_Ignore, I1W, I1H)
      SetGadgetAttribute(#Canvas, #PB_Canvas_Image, ImageID(#Img1))
    EndIf
  EndIf
EndProcedure
Procedure Rotate()
  Protected EventMenu
  EventMenu=EventMenu()
  Select EventMenu
    Case #Open
      OpenImage()
    Case #Left
      RotateLeft90()
    Case #Right
      RotateRight90()
  EndSelect
  If IsImage(#Img1)
    SetGadgetAttribute(#ScrollArea, #PB_ScrollArea_InnerWidth, ImageWidth(#Img1))
    SetGadgetAttribute(#ScrollArea, #PB_ScrollArea_InnerHeight, ImageHeight(#Img1))
    ResizeGadget(#Canvas, #PB_Ignore, #PB_Ignore, ImageWidth(#Img1), ImageHeight(#Img1))
    SetGadgetAttribute(#Canvas, #PB_Canvas_Image, ImageID(#Img1))
  EndIf
EndProcedure
Procedure myResize()
  ResizeGadget(#ScrollArea, #PB_Ignore, #PB_Ignore, WindowWidth(#MainWindow), WindowHeight(#MainWindow))
EndProcedure

OpenWindow(#MainWindow, 10, 10, 1024, 768, "Rotate90 test: [CTRL][O] select image, [L] rotate left, [R] rotate right", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
ScrollAreaGadget(#ScrollArea, 0, 0, WindowWidth(#MainWindow), WindowHeight(#MainWindow), 0, 0)
CanvasGadget(#Canvas, 0, 0, 0, 0)
CloseGadgetList()

AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Control|#PB_Shortcut_O, #Open)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_L, #left)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_R, #Right)

BindEvent(#PB_Event_Menu, @Rotate(), #MainWindow)
BindEvent(#PB_Event_SizeWindow, @myResize(), #MainWindow)


Repeat
  Event=WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit=#True
  EndSelect
Until Quit=#True

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 2:48 pm
by Saki
OMG :o
See you later

Re: Vector Lib: Rotate: Lost Pixels

Posted: Tue Mar 30, 2021 4:26 pm
by IdeasVacuum
Hi Rashad

That code works, but I have already incorporated the code from Luis, which is more advanced, taking care of transparency and the other orthogonal angles (180, 270). His code also delivers perfect results for horizontal and vertical mirror.

I don't need to rotate images by any other increment, though Luis's code does that too.

Re: Vector Lib: Rotate: Lost Pixels

Posted: Wed Mar 31, 2021 5:33 am
by netmaestro
This is the first flamewar in history where the participants call each other "dear". Usually the monikers are a bit more, shall we say, salty. Thanks guys.

Re: Vector Lib: Rotate: Lost Pixels

Posted: Wed Mar 31, 2021 9:57 am
by Saki
@Netmaestro

You shouldn't take this too seriously. :lol:

It's just the rustic exchange of experience and code.
The result is usually productive.

Best Regards Saki

Re: Vector Lib: Rotate: Lost Pixels

Posted: Fri Mar 11, 2022 5:58 am
by ozzie
I know there are often several ways to do the same thing, but I'd like to thank RASHAD for his code for rotating images Left90 and Right90 - the code suits my needs perfectly. I had previously tried using Vector Drawing but could only get Left90 to work - the others either ended up with a black image or a corrupted image. Using the PlgBlt approach the result is perfect and fast. Admittedly I did also want +180 and as my attempts to create a 'Rotate180' procedure were unsuccessful, I now call RotateRight90 twice! It's still fast and delivers a perfect result.