voila la fonction avec lissage pour image avec couche alpha, ça fonctionne nickel
Code : Tout sélectionner
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f, Mode.l) ; Rotation d'une image d'un angle en °
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, hdc.l, NewImageID, Mem, n, nn, bm.BITMAP
Angle = Angle * #PI / 180 ; On convertit en radian
Cos.f = Cos(Angle)
Sin.f = Sin(Angle)
CouleurFond = 0
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
Select Mode
Case 1
bmi2\bmiHeader\biWidth = bm\bmWidth
bmi2\bmiHeader\biHeight = bm\bmHeight
Case 2
bmi2\bmiHeader\biWidth = Round(Sqr(bm\bmWidth * bm\bmWidth + bm\bmHeight * bm\bmHeight), 1)
bmi2\bmiHeader\biHeight = bmi2\bmiHeader\biWidth
Default
bmi2\bmiHeader\biWidth = Round(bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin), 1)
bmi2\bmiHeader\biHeight = Round(bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin), 1)
EndSelect
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
hdc = CreateCompatibleDC_(GetDC_(ImageID))
If hdc
GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
DeleteDC_(hdc)
EndIf
CX1 = bm\bmWidth - 1
CY1 = bm\bmHeight - 1
CX2 = bmi2\bmiHeader\biWidth - 1
CY2 = bmi2\bmiHeader\biHeight - 1
Mem01 = Mem + bm\bmWidth * 4
Mem10 = Mem + 4
Mem11 = Mem01 + 4
Mem2Temp = Mem2
For nn = 0 To CY2
y1b.l = nn * 2 - CY2
Temp1.f = CX1 - y1b * Sin
Temp2.f = CY1 + y1b * Cos
For n = 0 To CX2
x1b.l = n * 2 - CX2
x1.f = (Temp1 + x1b * Cos) / 2
y1.f = (Temp2 + x1b * Sin) / 2
x2.l = x1
y2.l = y1
If x1 < x2
DEC x2
EndIf
If y1 < y2
DEC y2
EndIf
x2b = x2 + 1
y2b = y2 + 1
If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est completement en dehors de l'image
fx.f = x1 - x2
fy.f = y1 - y2
f00.f = (1 - fx) * (1 - fy)
f01.f = (1 - fx) * fy
f10.f = fx * (1 - fy)
f11.f = fx * fy
MemTemp = (x2 + y2 * bm\bmWidth) * 4
If x2 >= 0 And x2 <= CX1
If y2 >= 0 And y2 <= CY1
c00 = PeekL(Mem + MemTemp)
Else
c00 = 0
EndIf
If y2b >= 0 And y2b <= CY1
c01 = PeekL(Mem01 + MemTemp)
Else
c01 = 0
EndIf
Else
c00 = 0
c01 = 0
EndIf
If x2b >= 0 And x2b <= CX1
If y2 >= 0 And y2 <= CY1
c10 = PeekL(Mem10 + MemTemp)
Else
c10 = 0
EndIf
If y2b >= 0 And y2b <= CY1
c11 = PeekL(Mem11 + MemTemp)
Else
c11 = 0
EndIf
Else
c10 = 0
c11 = 0
EndIf
Channel00 = c00 >> 24 & $FF
Channel01 = c01 >> 24 & $FF
Channel10 = c10 >> 24 & $FF
Channel11 = c11 >> 24 & $FF
Alpha = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
Channel00 = c00 >> 16 & $FF
Channel01 = c01 >> 16 & $FF
Channel10 = c10 >> 16 & $FF
Channel11 = c11 >> 16 & $FF
Rouge = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
Channel00 = c00 >> 8 & $FF
Channel01 = c01 >> 8 & $FF
Channel10 = c10 >> 8 & $FF
Channel11 = c11 >> 8 & $FF
Vert = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
Channel00 = c00 & $FF
Channel01 = c01 & $FF
Channel10 = c10 & $FF
Channel11 = c11 & $FF
Bleu = Channel00 * f00 + Channel01 * f01 + Channel10 * f10 + Channel11 * f11
PokeL(Mem2Temp, Rouge | Vert << 8 | Bleu << 16 | Alpha << 24)
Else
PokeL(Mem2Temp, 0)
EndIf
Mem2Temp + 4
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight, 32)
hdc = CreateCompatibleDC_(GetDC_(ImageID(NewImageID)))
If hdc
SetDIBits_(hdc, ImageID(NewImageID), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
DeleteDC_(hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
;- ----------------------------------------
;- Test d'affichage d'image avec rotation
; On dessine une image
ImageNormale = CreateImage(#PB_Any, 80, 100, 32)
StartDrawing(ImageOutput(ImageNormale))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, 80, 100, $00000000)
DrawingMode(#PB_2DDrawing_Gradient | #PB_2DDrawing_AlphaBlend)
LinearGradient(0, 0, 80, 100)
GradientColor(0.0, $00000000)
GradientColor(1.0, $FF000000)
Box(0, 0, 80, 100)
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(5, 5, 35, 45, $B00000FF)
Box(40, 5, 35, 45, $FF00FF00)
Box(5, 50, 35, 45, $FFFF0000)
Box(40, 50, 35, 45, $80FFFFFF)
StopDrawing()
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 350, 400, "Effect - Rotation d'image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
End
EndIf
Angle.f = 30
Mode = 0
ImageRotation = RotateImageEx2(ImageID(ImageNormale), Angle, Mode)
TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, ImageID(ImageNormale))
RotationTexte = TextGadget(#PB_Any, 10, 200, 100, 15, "Rotation de 30°")
Rotation = ImageGadget(#PB_Any, 10, 215, 0, 0, ImageID(ImageRotation))
RotationTemps = TextGadget(#PB_Any, 180, 270, 170, 15, "")
TextGadget(#PB_Any, 180, 200, 100, 15, "Mode :")
OptionGadget(0, 180, 215, 170, 15, "normal")
OptionGadget(1, 180, 230, 170, 15, "sans redimensionnement")
OptionGadget(2, 180, 245, 170, 15, "avec redimensionnement fixe")
SetGadgetState(0, 1)
AddWindowTimer(0, 1, 200)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Timer
If EventTimer() = 1
Angle + 1
If Angle = 360
Angle = 0
EndIf
Temps1 = ElapsedMilliseconds()
For n = 1 To 100
FreeImage(ImageRotation)
ImageRotation = RotateImageEx2(ImageID(ImageNormale), Angle, Mode)
Next
Temps2 = ElapsedMilliseconds()
SetGadgetState(Rotation, ImageID(ImageRotation))
SetGadgetText(RotationTexte, "Rotation de " + Str(Angle) + "°")
SetGadgetText(RotationTemps, StrF((Temps2 - Temps1) / 100, 2) + "ms")
EndIf
ElseIf Event = #PB_Event_Gadget
Select EventGadget()
Case 0
Mode = 0
Case 1
Mode = 1
Case 2
Mode = 2
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
End