Seite 1 von 2

Image drehen?

Verfasst: 22.09.2009 00:35
von WernerZ
Mein DrawImage-Problem wurde super gelöst - aber jetzt stoße ich auf ein anderes Problem:

Wie kann ich ein Image um 90 Grad drehen? Ich kann keinen entsprechenden Befehl finden - nur im Sprite-Bereich, aber dort bion ich anscheinend auf bestimmte Größen beschränkt.

Gibt es für normale Bilder eine Rotate-Funktion?

Re: Image drehen?

Verfasst: 22.09.2009 09:33
von Rokur
Für Images gibt es keine Rotate-Funktion. Was hast du denn vor? In Spielen, die sowieso die Sprite-Library verwenden würde ich RotateSprite3D() verwenden. Die Größenvorgaben stören da eigentlich nicht weiter, du nimmst einfach die nächst größere Abmessung für dein Image und machst den Rest transparent.

Wenn du ein Image allerdings nur in 90° Schritten drehen willst, dann kannst du dir dafür doch schnell selber ne Procedure schreiben mit Point(), Plot(), usw.

Re: Image drehen?

Verfasst: 22.09.2009 10:36
von #NULL
zum drehen im rechten winkel:

Code: Alles auswählen

Procedure rotateImage90(image)
  
  If IsImage(image)
    Protected i.l, k.l
    Protected w=ImageWidth(image)-1
    Protected h=ImageHeight(image)-1
    Protected Dim p(w,h)
    StartDrawing( ImageOutput(image) )
      For k=0 To h
        For i=0 To w
          p(i,k)=Point(i,k)
        Next
      Next
    StopDrawing()
    
    If w<>h
      Swap w,h
      CreateImage(image,w+1,h+1)
    EndIf
    
    StartDrawing( ImageOutput(image) )
      For k=0 To h
        For i=0 To w
          Plot(i,k, p(k,w-i))
        Next
      Next
    StopDrawing()
    ProcedureReturn
  EndIf
  
EndProcedure



ww=800
wh=600
style | #PB_Window_ScreenCentered
style | #PB_Window_SystemMenu
style | #PB_Window_MinimizeGadget
hWin=OpenWindow(0, 50,100,ww,wh, "PRESS RETURN TO ROTATE",style)
ImageGadget(0,100,100,0,0,0)
AddKeyboardShortcut(0,#PB_Shortcut_Escape,10)
AddKeyboardShortcut(0,#PB_Shortcut_Return,11)

CreateImage(0,123,321)
StartDrawing(ImageOutput(0))
  Box(0,0,999,999,$004400)
  Line(0,0,123,321,$0000ff)
  Circle(30,10,6,$990000)
StopDrawing()
SetGadgetState(0,ImageID(0))

Repeat
  event=WaitWindowEvent(30)
  em=EventMenu()
  Select event
    Case #PB_Event_CloseWindow
      quit=1
    Case #PB_Event_Menu
      Select em
      Case 10
        quit=1
      Case 11
        rotateImage90(0)
        SetGadgetState(0,ImageID(0))
      EndSelect
  EndSelect
Until quit
zum rotieren in beliebigem winkel hab ich sonst auch was da, falls du das brauchst.

Re: Image drehen?

Verfasst: 22.09.2009 11:23
von WernerZ
Vielen Dank für die Antworten und vor allem für die Routine, die ich gleich ausprobieren werde!

Es geht um die automatisierte Erstellung von Visitenkarten mit Fotos, wobei die Fotos alle 90 Grad gedreht von der Kamera kommen.

Ich habe das gestern Nacht mit IrfanView gelöst, den ich einfach über den Folder mit den Bildern habe laufen lassen. Hat natürlich auch funktioniert, aber das ganze gleich im Code zu erledigen, wär eleganter und würde einen Schritt sparen.

Re: Image drehen?

Verfasst: 22.09.2009 11:50
von Rokur

Code: Alles auswählen

    If w<>h
      Swap w,h
      CreateImage(image,w+1,h+1)
    EndIf
   
    StartDrawing( ImageOutput(image) )
      For k=0 To h
        For i=0 To w
Bei jedem Drehen wird das Image dadurch 1 Pixel in breiter und höher, ich würde den Teil eher so schreiben:

Code: Alles auswählen

    If w<>h
      Swap w,h
      CreateImage(image,w,h)
    EndIf
   
    StartDrawing( ImageOutput(image) )
      For k=0 To h-1
        For i=0 To w-1
Anmerkung:
Wenn das Bild 50 Pixel breit ist, dann sind die gültigen X-Koordinaten 0-49 :wink:

Re: Image drehen?

Verfasst: 22.09.2009 12:37
von Kaeru Gaman
Rokur hat geschrieben:Bei jedem Drehen wird das Image dadurch 1 Pixel in breiter und höher
:?:
#NULL hat geschrieben:

Code: Alles auswählen

    Protected w=ImageWidth(image)-1
    Protected h=ImageHeight(image)-1
... erst lesen, dann basteln.

Re: Image drehen?

Verfasst: 22.09.2009 15:55
von inc.

Code: Alles auswählen

Procedure rotateImage90(image)
  
  If IsImage(image)
    Protected i.l, k.l
    Protected w=ImageWidth(image)-1
    Protected h=ImageHeight(image)-1
    Protected Dim p(w,h)
    StartDrawing( ImageOutput(image) )
      For k=0 To h
        For i=0 To w
          p(i,k)=Point(i,k)
        Next
      Next
    StopDrawing()
    
    If w<>h
      Swap w,h
      CreateImage(image,w+1,h+1)
    EndIf
    
    StartDrawing( ImageOutput(image) )
      For k=0 To h
        For i=0 To w
          Plot(i,k, p(k,w-i))
        Next
      Next
    StopDrawing()
    ProcedureReturn
  EndIf
  
EndProcedure
Die Routine oben ist leider PB bedingt grotten langsam. Das Problem ist hier die Verschachtelte For/Next Routine und vor allem der Plot() Befehl.

Bzgl. Plot() -> Lieber den DrawingBuffer direkt ansprechen, den DrawingBufferPitch mit einbeziehen und dann via While/Wend Routine in den Buffer des neuen Images schreiben.

In der Avisynth Library gibt es fantastische mmx/SSE Routinen für eben solch eine Bildbearbeitung, diese könnte man klasse zu PB hin portieren (ASM KnowHow Vorausgesetzt, denn die ASM Routinen dort sind in nASM verfasst), oder man macht eben aus jenen Parts eine .lib die man mit einem Include anbieten könnte.
Wermutstropfen ist aber, dass alles in Avsiynth GPL ist und man somit eine für nicht jeden Zweck optimale Lizenz aufgedrückt bekommt.
Oder ... man sucht im www nach solchen Routinen (Bicubic, Bilinear, Lanczos) die eine MIT oder was auch immer Lizenz besitzen.

Re: Image drehen?

Verfasst: 22.09.2009 16:16
von Rokur
Kaeru Gaman hat geschrieben:... erst lesen, dann basteln.
Ups, hast ja recht. :oops:
War nur etwas verwirrend, wenn Variablen, welche offensichtlich die Höhe und Breite eines Images darstellen sollen den bereits um 1 reduzierten Wert enthalten.

Re: Image drehen?

Verfasst: 22.09.2009 16:29
von Andesdaf
Mithilfe der Forensuche hätte man auch diesen Code im Codearchiv
gefunden, der auch Bilder drehen kann.

Re: Image drehen?

Verfasst: 22.09.2009 16:36
von ts-soft
Eine Lösung der ganz anderen Art wäre, man besitzt einen TFT mit Pivot Funktion
und dreht einfach den Bildschirm :lol: