Seite 2 von 3
Re: Bilder drehen
Verfasst: 21.11.2018 23:22
von ccode_new
@ts-soft!
Unter Linux z.B. so:
# Bild nach links drehen:
xrandr -o left
# Bild normal ausrichten:
xrandr -o normal
# Bild nach rechts drehen:
xrandr -o right
# Bild auf den Kopf drehen:
xrandr -o inverted
Aber das geht am Thema (etwas) vorbei.

Re: Bilder drehen
Verfasst: 21.11.2018 23:43
von ts-soft
Das ganze noch Crossplattform:

Jetzt ist aber Schluss mit Offtopi

Re: Bilder drehen
Verfasst: 21.11.2018 23:50
von #NULL
nehmt doch einfach runde Bilder, dann braucht ihr sie nicht drehen

Re: Bilder drehen
Verfasst: 21.11.2018 23:55
von HeX0R
ccode_new hat geschrieben:Hallo HeXOR!
[...]Du bist am Zug mir eine schnellere Procedure zu liefern.
Pfff... ich muss gar nix machen, ausser die beiden Prozeduren in eine nutzbare Testumgebung zu pappen.
Code: Alles auswählen
DisableDebugger
#USE_PLOT_AND_POINT = 0 ;<- change
InitNetwork()
UseJPEGImageDecoder()
Procedure RotiereEinBild(bild, richtung) ;<-- https://www.purebasic.fr/german/viewtopic.php?p=349925#p349925
Protected i.i, k.i
Protected rbild.i
Protected w.i = ImageWidth(bild)
Protected h.i = ImageHeight(bild)
Protected Dim p(w,h)
If IsImage(bild)
;Lese die Pixel
StartDrawing( ImageOutput(bild) )
For k=0 To h-1
For i=0 To w-1
p(i,k)=Point(i,k)
Next
Next
StopDrawing()
;Drehrichtung
If richtung = 0 ;"90° oder Pi/2"
If w<>h
Swap w,h
rbild = CreateImage(#PB_Any,w+1,h+1)
If IsImage(rbild)
FreeImage(bild)
EndIf
EndIf
StartDrawing( ImageOutput(rbild) )
For k=0 To h
For i=0 To w
Plot(i,k, p(k,w-i))
Next
Next
StopDrawing()
ElseIf richtung = 1 ;"180° oder Pi"
rbild = CreateImage(#PB_Any,w+1,h+1)
If IsImage(rbild)
FreeImage(bild)
EndIf
StartDrawing( ImageOutput(rbild) )
For k=0 To h-1
For i=0 To w-1
kk = (h-1)-k
ii = (w-1)-i
Plot(i,k, p(ii,kk))
Next
Next
StopDrawing()
ElseIf richtung = 2 ;"270° oder 3/2 * Pi"
If w<>h
Swap w,h
rbild = CreateImage(#PB_Any,w+1,h+1)
If IsImage(rbild)
FreeImage(bild)
EndIf
EndIf
StartDrawing( ImageOutput(rbild) )
For k=0 To h
For i=0 To w
kk = (h)-k
ii = (w)-i
Plot(i,k, p(kk,ii))
Next
Next
StopDrawing()
EndIf
ProcedureReturn rbild
EndIf
EndProcedure
Structure _SWAP_
StructureUnion
l.l[0]
b.b[0]
w.w[0]
EndStructureUnion
EndStructure
Procedure ROTATE(image, flag) ;<-- https://www.purebasic.fr/english/viewtopic.php?p=438200#p438200
;if flag <> 0 image rotates left else image rotates right
Protected A, B, result, padding, imgTemp, format
Protected *SBuf ; pointer to first memory byte of source buffer
Protected *DBuf ; pointer to first memory byte of destination buffer
Protected *FPix ; points to where first pixel is peeked in source buffer
Protected *S._SWAP_,*D._SWAP_ ; source and destination pointers
Protected Iw ; image width
Protected Ih ; image height
Protected Depth ; image color depth, 24 or 32
Protected SBpp ; SourceBytesPerPixel
Protected DBpp ; DestinationBytesPerPixel
Protected SPitch ; source image number of bytes per row (x)
Protected DPitch ; destination image number of bytes per row (x)
; Macro Copy3Bytes(Source, Destination)
; PokeA(Destination, PeekA(Source))
; PokeW(Destination+1, PeekW(Source+1))
; EndMacro
;
; Macro Copy4Bytes(Source, Destination)
; PokeL(Destination, PeekL(Source))
; EndMacro
Macro Copy3Bytes(Source, Destination)
Destination\w[0] = Source\w[0]
Destination\b[2] = Source\b[2]
EndMacro
Macro Copy4Bytes(Source, Destination)
Destination\l[0] = Source\l[0]
EndMacro
If IsImage(image) = 0 : ProcedureReturn result : EndIf
StartDrawing(ImageOutput(image))
; Get information for source image
Iw = OutputWidth() : Ih = OutputHeight() ; Get image size
*SBuf = DrawingBuffer()
SPitch = DrawingBufferPitch()
format = DrawingBufferPixelFormat()
Select format & $7FFF
Case #PB_PixelFormat_24Bits_RGB : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (RRGGBB)
Case #PB_PixelFormat_24Bits_BGR : SBpp = 3 : Depth = 24 ; 3 Bytes per pixel (BBGGRR)
Case #PB_PixelFormat_32Bits_RGB : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (RRGGBB)
Case #PB_PixelFormat_32Bits_BGR : SBpp = 4 : Depth = 32 ; 4 Bytes per pixel (BBGGRR)
Default
MessageRequester("Sorry...","24 and 32 bit depths only")
StopDrawing()
ProcedureReturn result
EndSelect
If format & #PB_PixelFormat_ReversedY = 0 ; this is for Linux
flag = flag ! 1 & 1
EndIf
StopDrawing()
; Create temporary image with axis swapped
Swap Ih,Iw
imgTemp = CreateImage(#PB_Any, Iw, Ih, 8*SBpp)
; perform the rotation
If imgTemp
StartDrawing(ImageOutput(imgTemp))
*DBuf = DrawingBuffer()
DPitch = DrawingBufferPitch()
DBpp = SBpp
If flag = 0 ; configure to rotate right
*FPix = *SBuf + (Ih-1) * SBpp ; point to last pixel in first row
SBpp = -SBpp ; reverse X iteration direction
Else ; configure to rotate left
*FPix = *SBuf + (Iw-1) * SPitch ; point to first pixel in last row
SPitch = -SPitch ; reverse Y iteration direction
EndIf
; time to fly
If Depth = 24
A = 0 : While A < Ih
*S = *FPix + (A * SBpp) ; set source pointer X position
*D = *DBuf + (A * DPitch) ; set destination pointer Y position
B = 0 : While B < Iw
Copy3Bytes(*S, *D)
*S + SPitch ; increment source pointer Y position
*D + DBpp ; increment destination pointer X position
B + 1 : Wend
A + 1 : Wend
ElseIf Depth = 32
A = 0 : While A < Ih
*S = *FPix + (A * SBpp) ; set source pointer X position
*D = *DBuf + (A * DPitch) ; set destination pointer Y position
B = 0 : While B < Iw
Copy4Bytes(*S, *D)
*S + SPitch ; increment source pointer Y position
*D + DBpp ; increment destination pointer X position
B + 1 : Wend
A + 1 : Wend
EndIf
StopDrawing()
FreeImage(image)
result = imgTemp
EndIf
ProcedureReturn result
EndProcedure
Procedure main()
Protected Image, ms
If ReceiveHTTPFile("https://images.pexels.com/photos/753626/pexels-photo-753626.jpeg?cs=srgb&dl=badeort-berg-bora-bora-753626.jpg&fm=jpg", GetTemporaryDirectory() + "pic.jpg")
Image = LoadImage(#PB_Any, GetTemporaryDirectory() + "pic.jpg")
If Image
ms = ElapsedMilliseconds()
CompilerIf #USE_PLOT_AND_POINT
Image = RotiereEinBild(Image, 0)
CompilerElse
Image = ROTATE(Image, 0)
CompilerEndIf
ms = ElapsedMilliseconds() - ms
If Image
OpenWindow(0, 0, 0, ImageWidth(Image), ImageHeight(Image), "")
ImageGadget(0, 0, 0, ImageWidth(Image), ImageHeight(Image), ImageID(Image))
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
CloseWindow(0)
MessageRequester("Needed time", Str(ms) + "ms")
EndIf
EndIf
EndIf
EndProcedure
main()
Plot und co: ~100ms
Buffer: 45ms!
Re: Bilder drehen
Verfasst: 22.11.2018 00:16
von ccode_new
@HeX0R
Ah!
Bei mir sieht es (ohne Debugger) so aus:
102 ms bei: ;Image = RotiereEinBild(Image, 0)
und:
218 ms bei: ;ROTATE(Image, 0)
Also genau umgekehrt.
Bei mir ist meine gepostete Procedure leider viel schneller!
Ich würde mich freuen, wenn mein Resultat von Anderen bestätigt werden könnte.
Mit Video-Ram / Shader ist aber noch viel schneller. (Dafür muss man aber Resize-Bilder als Sprites übergeben.)
Re: Bilder drehen
Verfasst: 22.11.2018 00:28
von HeX0R
Ich habe das nochmal geringfügig verfeinert, nun habe ich sogar 45ms bei DrawBuffer, ausserdem war die CopyImage() Funktion mit einem #PB_Any Handle sehr ungünstig gelöst und hat meinen Rechner hier ziemlich ins schwitzen gebracht.
Re: Bilder drehen
Verfasst: 22.11.2018 00:38
von ccode_new
@HeX0R
Ich habe mal mehrere Durchläufe getestet.
Mit DrawingBuffer ist es jetzt im Durchschnitt doch etwas schneller.
Manchmal liegen da 30 bis 300 ms Unterschied dazwischen.
Ich hatte aber auch einen Ausreißer, da war es mit DrawingBuffer langsamer.
Aber Shader schaffen es in unter 3 ms.
Also es wäre mir mit GPU-Unterstützung dann doch noch lieber.
Re: Bilder drehen
Verfasst: 22.11.2018 02:10
von ccode_new
#NULL hat geschrieben:nehmt doch einfach runde Bilder, dann braucht ihr sie nicht drehen

Das trifft leider auch nur auf dein Beispiel zu.
Die meisten runden Bilder dürften gedreht anders aussehen.

Re: Bilder drehen
Verfasst: 23.11.2018 07:51
von juergenkulow
Hallo ccode_new,
wenn ich Dich richtig verstanden habe willst Du ein 8k Bild in 3 ms per PB inline-ASM drehen, möglichst bei jedem Winkel.
Wie viel Zeit in Manntagen möchtest Du dafür investieren? Welche praktische Anwendung hat das?
Sollten neben dem 24, 32 bit-Format nicht auch High Dynamic Range(HDR)Formate unterstützt werden?
Gruß
Re: Bilder drehen
Verfasst: 23.11.2018 16:51
von ccode_new
juergenkulow hat geschrieben:wenn ich Dich richtig verstanden habe willst Du ein 8k Bild in 3 ms per PB inline-ASM drehen, möglichst bei jedem Winkel.
Das wäre wirklich toll!
Aber ich halte es für realitätsfern.
Von jeden Winkel habe ich nichts gesagt. (Das wäre aber auch toll.)
Wenn du eine schnelle Inline-Asm-Procedure zum Bilder drehen hast. (Es reicht 90, 180, 270 °) dann darfst du sie hier gerne posten.
Ich verbleibe mit freundlichem Gruß.