J'ai ouvert ce sujet sur le forum anglais a propos du problème de qualité de ResizeImage avec des PNG et couche Alpha
http://www.purebasic.fr/english/viewtop ... 7&p=315411
Et j'ai trouvé la solution du problème
Vous prenez cette image
et vous lancez ce code.
Le code est composé de 3 méthodes pour redimensionner un PNG :
- GDI plus : plus rapide mais de qualité moindre
- ResizeImage de PB avec ma correction : Plus rapide que ResizeImage sans correction et avec une meilleur qualité
- ResizeImage de PB sans correction : Qualité pas terrible car il y a un effet de bord avec les zone transparente de l'image
Code : Tout sélectionner
Procedure ResizeAlphaImage_GPIplus(Image1, Image2, Width, Height)
CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugCallback
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
CompilerEndIf
Protected hdc.i, input.GdiplusStartupInput, bmi.BITMAPINFO, bm.BITMAP, *token, *gfx, *image, GDIplus, *pPixels
#PixelFormat32bppARGB = $26200A
If IsImage(Image1)
; Get image
GetObject_(ImageID(Image1), 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
If bm\bmBitsPixel = 24
bmi\bmiHeader\biCompression = #BI_RGB
EndIf
*pPixels = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If *pPixels
hdc = CreateCompatibleDC_(GetDC_(ImageID(Image1)))
If hdc
GetDIBits_(hdc, ImageID(Image1), 0, bm\bmHeight, *pPixels, @bmi, #DIB_RGB_COLORS)
DeleteDC_(hdc)
EndIf
GDIplus = OpenLibrary(#PB_Any, "gdiplus.dll")
If GDIplus
Debug "GDI open"
input\GdiPlusVersion = 1
If CallFunction(GDIplus, "GdiplusStartup", @*token, @input, #Null) = 0
Debug "GDI start"
CallFunction(GDIplus, "GdipCreateBitmapFromScan0", ImageWidth(Image1), ImageHeight(Image1), SizeOf(RGBQUAD) * ImageWidth(Image1), #PixelFormat32bppARGB, *pPixels, @*image)
Debug "GDI scan0"
; Create Target image at 32bpp
ID = CreateImage(Image2, Width, Height, 32)
If Image2 = #PB_Any
Image2 = ID
EndIf
; Draw the Gdip bitmap object
hdc = StartDrawing(ImageOutput(Image2))
Box(0, 0, Width, Height, $FFFFFF)
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, Width, Height, 0)
CallFunction(GDIplus, "GdipCreateFromHDC", hdc, @*gfx)
CallFunction(GDIplus, "GdipDrawImageRectI", *gfx, *image, 0, 0, Width, Height)
StopDrawing()
CallFunction(GDIplus, "GdipDeleteGraphics", *gfx)
CallFunction(GDIplus, "GdipDisposeImage", *image)
CallFunction(GDIplus, "GdiplusShutdown", *token)
EndIf
CloseLibrary(GDIplus)
EndIf
FreeMemory(*pPixels)
EndIf
EndIf
ProcedureReturn Image2
EndProcedure
Procedure ResizeAlphaImage(Image1, Image2, Width, Height)
oWidth = ImageWidth(Image1)
oHeight = ImageHeight(Image1)
ID = CreateImage(Image2, oWidth, oHeight, 32)
If Image2 = #PB_Any
Image2 = ID
EndIf
StartDrawing(ImageOutput(Image2))
Box(0, 0, oWidth, oHeight, $FFFFFF)
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, oWidth, oHeight, 0)
DrawingMode(#PB_2DDrawing_Default)
DrawAlphaImage(ImageID(Image1), 0, 0)
StopDrawing()
ResizeImage(Image2, Width, Height, #PB_Image_Smooth)
ProcedureReturn Image2
EndProcedure
UsePNGImageDecoder()
LoadImage(0, "Resize_Bug_png1.png")
Time1 = ElapsedMilliseconds()
Counter = 200
ResizeX = 2
ResizeY = 2
For i = 1 To Counter
ResizeAlphaImage_GPIplus(0, 1, ImageWidth(0) * ResizeX, ImageHeight(0) * ResizeY)
Next
Time2 = ElapsedMilliseconds()
For i = 1 To Counter
ResizeAlphaImage(0, 2, ImageWidth(0) * ResizeX, ImageHeight(0) * ResizeY)
Next
Time3 = ElapsedMilliseconds()
For i = 1 To Counter
CopyImage(0, 3)
ResizeImage(3, ImageWidth(0) * ResizeX, ImageHeight(0) * ResizeY, #PB_Image_Smooth)
Next
Time4 = ElapsedMilliseconds()
MessageRequester("Time", "GDIplus = " + Str((Time2 - Time1) / Counter) + " ms" + Chr(10) + "PB (with correction) = " + Str((Time3 - Time2) / Counter) + " ms" + Chr(10) + "PB = " + Str((Time4 - Time3) / Counter) + " ms")
OpenWindow(0, 0, 0, ImageWidth(1) * 3, ImageHeight(1) + ImageHeight(0), "Resized Image", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
SetWindowColor(0, $FF00FF)
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
ImageGadget(1, 0, ImageHeight(0), 0, 0, ImageID(1))
ImageGadget(2, ImageWidth(1), ImageHeight(0), 0, 0, ImageID(2))
ImageGadget(3, ImageWidth(1) * 2, ImageHeight(0), 0, 0, ImageID(3))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow