Vector Lib: Rotate: Lost Pixels

Windows specific forum
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Vector Lib: Rotate: Lost Pixels

Post by Saki »

Interesting :wink:
Last edited by Saki on Tue Mar 30, 2021 2:51 pm, edited 4 times in total.
地球上の平和
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Vector Lib: Rotate: Lost Pixels

Post 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
Egypt my love
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vector Lib: Rotate: Lost Pixels

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Vector Lib: Rotate: Lost Pixels

Post 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.
地球上の平和
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Vector Lib: Rotate: Lost Pixels

Post 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
Egypt my love
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Vector Lib: Rotate: Lost Pixels

Post by Saki »

OMG :o
See you later
地球上の平和
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vector Lib: Rotate: Lost Pixels

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Vector Lib: Rotate: Lost Pixels

Post 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.
BERESHEIT
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Vector Lib: Rotate: Lost Pixels

Post 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
地球上の平和
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: Vector Lib: Rotate: Lost Pixels

Post 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.
Post Reply