PureBasic

Forums PureBasic
Nous sommes le Sam 24/Aoû/2019 9:03

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 6 messages ] 
Auteur Message
 Sujet du message: ResizeImage - Problème de qualité
MessagePosté: Mar 09/Fév/2010 23:01 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4312
Localisation: Clermont ferrand OU Olsztyn
Salut,

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
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:
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


Le résultat donne cela :
Image

_________________
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: ResizeImage - Problème de qualité
MessagePosté: Mer 10/Fév/2010 10:18 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4312
Localisation: Clermont ferrand OU Olsztyn
une solution plus rapide encore

Code:
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(Image, Width, Height)
   Protected x, x1, x2, Memoire, Image_HDC, Image_Ancienne, Image_Bitmap.BITMAP, Image_BitmapInfo.BITMAPINFO
   If IsImage(Image)
      
      ; Chargement du HDC
      Image_HDC = CreateCompatibleDC_(#Null)
      Image_Ancienne = SelectObject_(Image_HDC, ImageID(Image))
      
      ; Dimension de l'image
      GetObject_(ImageID(Image), SizeOf(BITMAP), @Image_Bitmap)
      Image_BitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
      Image_BitmapInfo\bmiHeader\biWidth = Image_Bitmap\bmWidth
      Image_BitmapInfo\bmiHeader\biHeight = Image_Bitmap\bmHeight
      Image_BitmapInfo\bmiHeader\biPlanes = 1
      Image_BitmapInfo\bmiHeader\biBitCount = 32
      
      ; Zone mémoire pour copier l'image
      xx = Image_Bitmap\bmWidth * Image_Bitmap\bmHeight - 1
      Protected Dim Memoire(xx)
      
      ; Copie de l'image en mémoire
      GetDIBits_(Image_HDC, ImageID(Image), 0, Image_Bitmap\bmHeight, @Memoire(), @Image_BitmapInfo, #DIB_RGB_COLORS)
      
      ; Modification de l'image en mémoire
      For x = 0 To xx
         If Memoire(x) = 0
            Memoire(x) = $00FFFFFF
         EndIf
      Next
      
      ; Transfert de la mémoire dans la l'image de base
      SetDIBits_(Image_HDC, ImageID(Image), 0, Image_Bitmap\bmHeight,  @Memoire(), @Image_BitmapInfo, #DIB_RGB_COLORS)
      
      ; Fermeture du HDC
      SelectObject_(Image_HDC, Image_Ancienne)
      DeleteDC_(Image_HDC)
      
      ResizeImage(Image, Width, Height, #PB_Image_Smooth)
   EndIf
EndProcedure

Procedure ResizeAlphaImage2(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, "ResizeAlphaImage3.png")

Time1 = ElapsedMilliseconds()
Counter = 50
ResizeX = 4
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
   
   CopyImage(0, 2)
   ResizeAlphaImage(2, ImageWidth(0) * ResizeX, ImageHeight(0) * ResizeY)
   
Next
Time3 = ElapsedMilliseconds()
For i = 1 To Counter
   
   ResizeAlphaImage2(0, 3, ImageWidth(0) * ResizeX, ImageHeight(0) * ResizeY)
   
Next
Time4 = ElapsedMilliseconds()
For i = 1 To Counter
   
   CopyImage(0, 4)
   ResizeImage(4, ImageWidth(0) * ResizeX, ImageHeight(0) * ResizeY, #PB_Image_Smooth)
   
Next
Time5 = ElapsedMilliseconds()


OpenWindow(0, 0, 0, ImageWidth(1) * 2, ImageHeight(1) * 2 + ImageHeight(0) + 48, "Resized Image", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
SetWindowColor(0, $FF00FF)
TextGadget(#PB_Any, 0, 0, ImageWidth(0), 16, "Normal", #PB_Text_Center)
ImageGadget(0, 0, 16, 0, 0, ImageID(0))
TextGadget(#PB_Any, 0, 16 + ImageHeight(0), ImageWidth(1), 16, "Resize GDI = " + StrF((Time2 - Time1) / Counter, 1) + " ms", #PB_Text_Center)
ImageGadget(1, 0, 32 + ImageHeight(0), 0, 0, ImageID(1))
TextGadget(#PB_Any, ImageWidth(1), 16 + ImageHeight(0), ImageWidth(1), 16, "Resize PB with correction API = " + StrF((Time3 - Time2) / Counter, 1) + " ms", #PB_Text_Center)
ImageGadget(2, ImageWidth(1), 32 + ImageHeight(0), 0, 0, ImageID(2))
TextGadget(#PB_Any, ImageWidth(1), 32 + ImageHeight(0) + ImageHeight(1), ImageWidth(1), 16, "Resize PB with correction PB = " + StrF((Time4 - Time3) / Counter, 1) + " ms", #PB_Text_Center)
ImageGadget(3, ImageWidth(1), 48 + ImageHeight(0) + ImageHeight(1), 0, 0, ImageID(3))
TextGadget(#PB_Any, 0, 32 + ImageHeight(0) + ImageHeight(1), ImageWidth(1), 16, "Resize PB = " + StrF((Time5 - Time4) / Counter, 1) + " ms", #PB_Text_Center)
ImageGadget(4, 0, 48 + ImageHeight(0) + ImageHeight(1), 0, 0, ImageID(4))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

_________________
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: ResizeImage - Problème de qualité
MessagePosté: Mer 10/Fév/2010 13:11 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8739
Hum je ne vois pas vraiment de différence entre "resize et resize avec correction" sur ton screenshot

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
RESIZER GOLD : Mon logiciel de redimensionnement par lot 100% PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: ResizeImage - Problème de qualité
MessagePosté: Mer 10/Fév/2010 14:57 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 27/Oct/2006 12:19
Messages: 1224
Localisation: Calvados (14)
Ar-S a écrit:
Hum je ne vois pas vraiment de différence entre "resize et resize avec correction" sur ton screenshot


Je vois un trait "violet" a gauche et à droite du bouton sans la correction, est-ce là le problème ?

_________________
Image

Image


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: ResizeImage - Problème de qualité
MessagePosté: Mer 10/Fév/2010 16:12 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8739
Tu as raison mais je le vois aussi avec la correction

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
RESIZER GOLD : Mon logiciel de redimensionnement par lot 100% PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: ResizeImage - Problème de qualité
MessagePosté: Mer 10/Fév/2010 16:55 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4312
Localisation: Clermont ferrand OU Olsztyn
il y a un effet de bord sur l'image sans la correction (à gauche), en gros un trait foncé sur le contour de l'image alors que sur l'image du centre, il n'y a pas de bordure noire.

Voilà un zoom sur le défaut
Image donne Image avec une espèce de bord noir flou alors qu'il n'existe pas sur l'image d'origine

J'ai vu ça car j'avais des traits en redimensionnant des PNG et je ne comprenais d'où ils venaient



Avec la correction, c'est parfait (si tu vois un bord noir entre le rose et le beige, c'est ton écran qui donne cet effet, essai le code en mettant le fond de la fenêtre en blanc et tu verras :) )

_________________
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 6 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 2 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye