Da ich aber dafür nur sehr langsame Funktionen oder welche die API Funktionen verwenden fand habe ich mich mal selbst dran versucht.
Hier nun das Ergebnis vielleicht kann es ja noch jemand brauchen bzw. vielleicht hat ja jemand sogar eine Idee wie man es noch schneller lösen kann.
Update:
Code ist überarbeitet sollte im Gegensatz zu dem davor nur fehlerfrei sein und ist auf jeden Fall einiges schneller ist aber nur für 32 Bit Images da für 24 Bit Images das ganze erheblich langsamer wäre.
Update 2:
Code erneut überarbeitet ist jetzt nochmal etwas schneller vor allem bei quadratischen Bildern.
Code: Alles auswählen
EnableExplicit
Procedure.i RotateImage32Bit(SourceImage32Bit.i, Rotate.i = 90, InPlace.i = #False)
Protected Width.i, Height.i, ResultImage32Bit.i, ImageByteSize.i, SourceBuffer.i, ResultBuffer.i, Pos1.i, Pos2.i, Row.i
Protected *SourcePixel.Long, *ResultPixel.Long
If Not IsImage(SourceImage32Bit) Or Not ImageDepth(SourceImage32Bit, #PB_Image_InternalDepth) = 32 : ProcedureReturn #False : EndIf
Width = ImageWidth(SourceImage32Bit)
Height = ImageHeight(SourceImage32Bit)
ImageByteSize = Width * Height * 4
Rotate = Rotate % 360
If Rotate < 0 : Rotate + 360 : EndIf
If Rotate = 0
If InPlace
ProcedureReturn SourceImage32Bit
Else
ProcedureReturn CopyImage(SourceImage32Bit, #PB_Any)
EndIf
EndIf
If Width = Height
If InPlace
ResultImage32Bit = SourceImage32Bit
Else
ResultImage32Bit = CopyImage(SourceImage32Bit, #PB_Any)
EndIf
StartDrawing(ImageOutput(ResultImage32Bit))
SourceBuffer = DrawingBuffer()
StopDrawing()
Select Rotate
Case 90
Row = Width * 4 - 4
ImageByteSize / 4
While ImageByteSize
*SourcePixel = SourceBuffer + Pos1 + Pos2 * Width
*ResultPixel = SourceBuffer + Pos2 + (Row - Pos1) * Width
Swap *ResultPixel\l, *SourcePixel\l
*ResultPixel = SourceBuffer + (Row - Pos1) + (Row - Pos2) * Width
Swap *ResultPixel\l, *SourcePixel\l
*ResultPixel = SourceBuffer + (Row - Pos2) + Pos1 * Width
Swap *ResultPixel\l, *SourcePixel\l
Pos1 + 4
If Pos1 > Width << 1
Pos2 + 4
Pos1 = 0
EndIf
ImageByteSize - 4
Wend
Case 180
*SourcePixel = SourceBuffer
*ResultPixel = SourceBuffer + ImageByteSize - 4
ImageByteSize / 2
While ImageByteSize
Swap *ResultPixel\l, *SourcePixel\l
*SourcePixel + 4
*ResultPixel - 4
ImageByteSize - 4
Wend
Case 270
Row = Width * 4 - 4
ImageByteSize / 4
While ImageByteSize
*SourcePixel = SourceBuffer + Pos1 + Pos2 * Width
*ResultPixel = SourceBuffer + (Row - Pos2) + Pos1 * Width
Swap *ResultPixel\l, *SourcePixel\l
*ResultPixel = SourceBuffer + (Row - Pos1) + (Row - Pos2) * Width
Swap *ResultPixel\l, *SourcePixel\l
*ResultPixel = SourceBuffer + Pos2 + (Row - Pos1) * Width
Swap *ResultPixel\l, *SourcePixel\l
Pos1 + 4
If Pos1 > Width << 1
Pos2 + 4
Pos1 = 0
EndIf
ImageByteSize - 4
Wend
EndSelect
Else
If Rotate <> 180 : Swap Width, Height : EndIf
StartDrawing(ImageOutput(SourceImage32Bit))
SourceBuffer = DrawingBuffer()
StopDrawing()
ResultImage32Bit = CreateImage(#PB_Any, Width, Height, 32)
StartDrawing(ImageOutput(ResultImage32Bit))
ResultBuffer = DrawingBuffer()
StopDrawing()
Select Rotate
Case 90
Pos2 = ImageByteSize - 4 * Width
While Pos1 < ImageByteSize
*SourcePixel = SourceBuffer + Pos1
*ResultPixel = ResultBuffer + Pos2
*ResultPixel\l = *SourcePixel\l
Pos1 + 4
Pos2 - 4 * Width
If Pos2 < 0
Pos2 = ImageByteSize - 4 * Width
ResultBuffer + 4
EndIf
Wend
Case 180
*SourcePixel = SourceBuffer
*ResultPixel = ResultBuffer + ImageByteSize - 4
While ImageByteSize
*ResultPixel\l = *SourcePixel\l
*SourcePixel + 4
*ResultPixel - 4
ImageByteSize - 4
Wend
Case 270
ResultBuffer + 4 * Width - 4
While Pos1 < ImageByteSize
*SourcePixel = SourceBuffer + Pos1
*ResultPixel = ResultBuffer + Pos2
*ResultPixel\l = *SourcePixel\l
Pos1 + 4
Pos2 + 4 * Width
If Pos2 > ImageByteSize-4
Pos2 = 0
ResultBuffer - 4
EndIf
Wend
EndSelect
EndIf
ProcedureReturn ResultImage32Bit
EndProcedure
; Beispiel
Define Image.i, Font.i, RotatedImage.i
Image = CreateImage(#PB_Any, 400, 300, 32)
Font = LoadFont(#PB_Any, "Arial", 100)
StartDrawing(ImageOutput(Image))
DrawingFont(FontID(Font))
DrawText(200 - TextWidth("Test") / 2, 150 - TextHeight("Test") / 2, "Test", RGB(255,255,255), RGB(0,0,255))
StopDrawing()
RotatedImage = RotateImage32Bit(Image)
OpenWindow(0, 0, 0, 800, 400, "RotateImage Beispiel", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ImageGadget(0, 0, 0, 400, 400, ImageID(Image))
ImageGadget(1, 400, 0, 40, 40, ImageID(RotatedImage))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow