Bild im Uhrzeigersinn drehen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Bud
Beiträge: 1
Registriert: 25.12.2006 19:06
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Bud »

Kaeru Gaman hat geschrieben: ... vielleicht hab ich auch nur nen ganz blöden Typo reingehaun,
aber dann hab ich fünfmal dran vorbei geguckt... also, ich raffs nicht.
Ja, hast du:

Code: Alles auswählen

For y=0 To Heigth -1
Heigth gibt's nicht, also wird die Schleife garnicht ausgeführt. ^^
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

Kaeru Gaman hat geschrieben:... vielleicht hab ich auch nur nen ganz blöden Typo reingehaun,
aber dann hab ich fünfmal dran vorbei geguckt... also, ich raffs nicht.
EnableExplicit?
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

UND DAS MIR! Bild


ok, so funzts:

Code: Alles auswählen

EnableExplicit

OpenWindow(0, 0,0, 600,600, "test")

LoadImage(0,"Test_In.bmp")

Define Width  = ImageWidth(0)
Define Height = ImageHeight(0)
Define x, y, n

ImageGadget(0, 4,4, Width, Height, ImageID(0))
      While WindowEvent() :  Wend

Dim Col.l ( Width, Height )

  For x=0 To Width -1
   StartDrawing(ImageOutput(0))
      For y=0 To Height -1
        Col( x,y ) = Point(x,y)
        Plot( x,y, Col (x,y) & 255 )
      Next
   StopDrawing()
      SetWindowTitle(0, "Line: " + Str(x) )
      SetGadgetState(0, ImageID(0) )
      While WindowEvent() :  Wend
  Next

For n=0 To 99
  Debug Col( n, 50 )
Next

ResizeImage(0, Height, Width)

ResizeGadget(0, 4,4, Height, Width )
SetGadgetState(0, ImageID(0) )
While WindowEvent() :  Wend

  For y=0 To Width -1
   StartDrawing(ImageOutput(0))
      For x=0 To Height -1
        Plot( x,y , Col( y, x ) )
      Next
   StopDrawing()
      SetWindowTitle(0, "Line: " + Str(Y) )
      SetGadgetState(0, ImageID(0) )
      While WindowEvent() :  Wend
  Next


Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
SaveImage(0,"Test_Out.bmp")
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Tompazi
Beiträge: 211
Registriert: 22.09.2007 15:38

Beitrag von Tompazi »

Das ist aber Langsamer als mein code (?)

MfG Tompazi
Bild
Burstnibbler
Beiträge: 58
Registriert: 04.10.2008 12:10

Beitrag von Burstnibbler »

Hallo,

hier nochmal die Routine mit ´nem Pixelbuffer.

Code: Alles auswählen

EnableExplicit
;
#Image=0
;
Define *PixelBuffer
Define.i BufferPtr, OldTime, NewTime
Define.l X, Y, ImgWidth, ImgHeight
;
Oldtime=ElapsedMilliseconds()
;
LoadImage(#Image,"Test.Bmp")
ImgWidth=ImageWidth(#Image)
ImgHeight=ImageHeight(#Image)
*PixelBuffer=AllocateMemory(ImgWidth*ImgHeight*4)
BufferPtr= *PixelBuffer
;Auslesen
StartDrawing(ImageOutput(#Image))
 For Y=0 To ImgHeight-1
  For X=0 To ImgWidth-1
   PokeL(BufferPtr,Point(X,Y))
   BufferPtr+4
  Next
 Next
StopDrawing()
;
ResizeImage(#Image,ImgHeight,ImgWidth)
;"Drehen" & Zeichnen
StartDrawing(ImageOutput(#Image))
 For X=0 To ImgHeight-1
  For Y=ImgWidth-1 To 0 Step -1
   Plot(X,Y,PeekL(BufferPtr))
   BufferPtr-4
  Next
 Next
StopDrawing()
;
FreeMemory(*PixelBuffer)
SaveImage(#Image,"DrehTest.bmp")
;
NewTime=ElapsedMilliseconds()-Oldtime
MessageRequester("Info",Str(Newtime)+" ms")
End
MfG,
Burstnibbler
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Tompazi hat geschrieben:Das ist aber Langsamer als mein code (?)
ja latürnich, weil ich jede zeile anzeigen lasse.

nimm den ganzen window-krempel wieder raus, zumindest die zeilenweise aktualisierung und anzeige.

Code: Alles auswählen

EnableExplicit

OpenWindow(0, 0,0, 600,600, "test")

LoadImage(0,"Test_In.bmp")

Define Width  = ImageWidth(0)
Define Height = ImageHeight(0)
Define x, y, n

ImageGadget(0, 4,4, Width, Height, ImageID(0))
      While WindowEvent() :  Wend

Dim Col.l ( Width, Height )

   StartDrawing(ImageOutput(0))
    For x=0 To Width -1
      For y=0 To Height -1
        Col( x,y ) = Point(x,y)
      Next
    Next
   StopDrawing()

ResizeImage(0, Height, Width)

ResizeGadget(0, 4,4, Height, Width )
SetGadgetState(0, ImageID(0) )
While WindowEvent() :  Wend

   StartDrawing(ImageOutput(0))
    For y=0 To Width -1
      For x=0 To Height -1
        Plot( x,y , Col( y, x ) )
      Next
    Next
   StopDrawing()

SetGadgetState(0, ImageID(0) )

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
SaveImage(0,"Test_Out.bmp")
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Richtig Spaß machts natürlich erst, wenn man direkt auf die Bitplanes der Images zugreift. Also nicht erst über Point(x,y,) die Farbe ausliest.

Kaeru, Deine Version spiegelt das Image leider, wenn es sich um ein bottom-up BMP handelt. Ich habe ein Bild mit Schriftzug benutzt und das ist nach dem drehen spiegelverkehrt.

Hier mal ein ein code, der dies beachtet und außerdem sehr schnell ist (1500ms Tompazis Version, 45ms meine Version). Der Speicherverbrauch für das Drehen ist exakt der von 2 Bildern, nicht mehr.
Ich denke, daß ist die schnellste und eleganteste Methode für fixe Bildmanipulation.

Achtung: Der code ist nicht mit der DEMO Version vom PB compilierbar, wegen API Aufrufe.

Code: Alles auswählen

EnableExplicit

Enumeration 
	#Image_Original
	#Image_Gedreht
EndEnumeration

Structure Image
  dsBitmap.BITMAP               ; Bitmapstruktur des Images
  
  ;   LONG   bmType;
  ;   LONG   bmWidth;
  ;   LONG   bmHeight;
  ;   LONG   bmWidthBytes;      ; tatsächliche Breite der Bitplane
  ;   WORD   bmPlanes;
  ;   WORD   bmBitsPixel;       ; Bittiefe der Bitplane
  ;   LPVOID bmBits;            ; Zeiger auf den memorybereich
EndStructure

Global Original.Image
Global Gedreht.Image

Define.i OldTime, NewTime
Define.l Ori, Ged, X, Y, Pixel

Oldtime=ElapsedMilliseconds()

LoadImage(#Image_Original,"Test.Bmp")			; MUSS für dieses Beispiel ein 24 Bit bmp-Bild sein!

GetObject_(ImageID(#Image_Original), SizeOf(BITMAP), @Original\dsBitmap)
CreateImage(#Image_Gedreht, Original\dsBitmap\bmHeight, Original\dsBitmap\bmWidth, 24)	; Achtung, die Ausmaße sind hier genau um 90 Grad gedreht, als beim Original!
GetObject_(ImageID(#Image_Gedreht), SizeOf(BITMAP), @Gedreht\dsBitmap)


For Y = 0 To Original\dsBitmap\bmHeight - 1
  For X = 0 To Original\dsBitmap\bmWidth - 1
    
    ; Hier werden jetzt 3 Byte aus der Bitplanes des Quellimages kopiert (R,G,B) und in die Bitplane des Zielimages geschrieben.
    ; das Drehen wird durch vertauschen der X und Y Richtungen erreicht.

    ; Adresse = Beginn der Bilddaten + (X * 3 [1 RGB-Pixel = 24 Bit = 3 Bytes] + Y * Breite des Bildes in Bytes [Hier könnte man auch bmWidth * 3 nehmen]
    ;Ori = Original\dsBitmap\bmBits + X * 3 + Y * Original\dsBitmap\bmWidthBytes
    ;Ged = Gedreht\dsBitmap\bmBits + Y * 3 + X * Gedreht\dsBitmap\bmWidthBytes
    
    ; Da die obere Formel das Bild leider spiegelverkehrt rechnet (Grund: Quellbild hat eine bottom-up Bitmap [siehe wikipedia]), muss man bei der Transformierung das ganze noch spiegeln.
    Ori = Original\dsBitmap\bmBits + X * 3 + Y * Original\dsBitmap\bmWidthBytes
    Ged = Ged = Gedreht\dsBitmap\bmBits + Y * 3 + (Gedreht\dsBitmap\bmWidthBytes * Gedreht\dsBitmap\bmHeight - X * Gedreht\dsBitmap\bmWidthBytes)
        
    PokeL(Ged, PeekL(Ori) )
    
  Next X
Next Y

SaveImage(#Image_Gedreht,"DrehTest.bmp")
;
NewTime=ElapsedMilliseconds()-Oldtime
MessageRequester("Info",Str(Newtime)+" ms")
End 
Gruß Kurzer
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Kurzer hat geschrieben:Richtig Spaß machts natürlich erst, wenn man direkt auf die Bitplanes der Images zugreift. Also nicht erst über Point(x,y,) die Farbe ausliest.
definif!
... ich war aber zu faul, nachzusuchen wie man das macht.
Kurzer hat geschrieben:Kaeru, Deine Version spiegelt das Image leider, wenn es sich um ein bottom-up BMP handelt. Ich habe ein Bild mit Schriftzug benutzt und das ist nach dem drehen spiegelverkehrt.
verdammt, wie kann man nur so viele fehler in so wenig code reinhaun!

das ist unabhängig davon, ob es ein bottom-up ist oder nicht.
es ist einfach falschrum gemacht, nicht richtig mitgedacht.

man muss beim plotten eine koordinate umdrehen.
für -90°:

Code: Alles auswählen

        Plot( x,y , Col( y, Height - x -1 ) )
für +90°:

Code: Alles auswählen

        Plot( x,y , Col( Width -y -1, x ) )
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Kaeru Gaman hat geschrieben:das ist unabhängig davon, ob es ein bottom-up ist oder nicht.
es ist einfach falschrum gemacht, nicht richtig mitgedacht.
Ach. oO Siehste, ich hab's auf bottom-up geschoben.
Naja, *schluterzuck* Nobody is perfect. :D
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Tompazi
Beiträge: 211
Registriert: 22.09.2007 15:38

Beitrag von Tompazi »

@Kurzer
Geht das auch Linux kompatibel? s.v.p.

MfG Tompazi
Bild
Antworten