Seite 2 von 3

Verfasst: 31.05.2009 14:18
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. ^^

Verfasst: 31.05.2009 14:21
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?

Verfasst: 31.05.2009 14:25
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")

Verfasst: 31.05.2009 15:57
von Tompazi
Das ist aber Langsamer als mein code (?)

MfG Tompazi

Verfasst: 01.06.2009 02:43
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

Verfasst: 01.06.2009 10:47
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")

Verfasst: 01.06.2009 12:35
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

Verfasst: 01.06.2009 12:46
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 ) )

Verfasst: 01.06.2009 13:09
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

Verfasst: 01.06.2009 15:00
von Tompazi
@Kurzer
Geht das auch Linux kompatibel? s.v.p.

MfG Tompazi