Meilleure qualité de ResizeImage avec couche Alpha

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Meilleure qualité de ResizeImage avec couche Alpha

Message par Le Soldat Inconnu »

N'en déplaise à Fred mais le redimensionnement des images avec couche alpha à un gros Bug

Bug qui vient de la gestion de la couche alpha faite par PB

en effet, les zone de l'image totalement transparente doivent s'écrire avec la couleur $00FFFFFF et pas $00000000
Et c'est cette erreur qui cause un résultat, n’ayons pas peur des mots, merdique avec ResizeImage

voici un palliatif en espérant un prise en compte avant la version 157.12 :mrgreen:

je vous laisse observer la différence, je pense que ça se passe de commentaire, il y a une belle bordure noire qui apparait avec le resize de PB
Image

Code : Tout sélectionner

Procedure ResizeAlphaImage(Image, Width, Height, Quality = #PB_Image_Smooth)
	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, Quality)
	EndIf
EndProcedure



; Création d'une image avec couche Alpha
CreateImage(0, 64, 64, 32 | #PB_Image_Transparent)
StartDrawing(ImageOutput(0))
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	Box(4, 4, 24, 24, $FFFF00FF)
	LineXY(32, 4, 63, 24, $FF80FF80)
	LineXY(32, 24, 63, 4, $FF8080FF)
	RoundBox(4, 36, 24, 24, 4, 8, $FF00A0FF)
	Circle(48, 48, 12, $FFFF00FF)
StopDrawing()
CopyImage(0, 1)
CopyImage(0, 2)

ResizeImage(1, 128, 128, #PB_Image_Smooth)

ResizeAlphaImage(2, 128, 128, #PB_Image_Smooth)

; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 600, 600, "ResizeImage", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
  End
EndIf

TextGadget(#PB_Any, 4, 4, 300, 16, "Image original")
ImageGadget(#PB_Any, 4, 20, 64, 64, ImageID(0))
TextGadget(#PB_Any, 4, 144, 300, 16, "Image agrandie : ResizeImage (PB)")
ImageGadget(#PB_Any, 4, 160, 128, 128, ImageID(1))
TextGadget(#PB_Any, 4, 288, 300, 16, "Image agrandie : ResizeAlphaImage")
ImageGadget(#PB_Any, 4, 304, 128, 128, ImageID(2))

Repeat
  Event = WaitWindowEvent()
  
  Select Event
		Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
          
			EndSelect
	EndSelect
  
Until Event = #PB_Event_CloseWindow
Le rapport de bug est la :
http://www.purebasic.fr/english/viewtop ... 14#p353314
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)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par Le Soldat Inconnu »

Version compatible tout OS

Code : Tout sélectionner

Procedure ResizeAlphaImage(Image, Width, Height, Quality = #PB_Image_Smooth)
	Protected ID, oWidth, oHeight
	If IsImage(Image)
		oWidth = ImageWidth(Image)
		oHeight = ImageHeight(Image)
		ID = CreateImage(#PB_Any, oWidth, oHeight, 32)
		StartDrawing(ImageOutput(ID))
			Box(0, 0, oWidth, oHeight, $FFFFFF)
			DrawingMode(#PB_2DDrawing_AlphaChannel)
			Box(0, 0, oWidth, oHeight, 0)
			DrawingMode(#PB_2DDrawing_Default)
			DrawAlphaImage(ImageID(Image), 0, 0)
		StopDrawing()
		ResizeImage(ID, Width, Height, #PB_Image_Smooth)
		CopyImage(ID, Image)
		FreeImage(ID)
	EndIf
EndProcedure



; Création d'une image avec couche Alpha
CreateImage(0, 64, 64, 32 | #PB_Image_Transparent)
StartDrawing(ImageOutput(0))
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	Box(4, 4, 24, 24, $FFFF00FF)
	LineXY(32, 4, 63, 24, $FF80FF80)
	LineXY(32, 24, 63, 4, $FF8080FF)
	RoundBox(4, 36, 24, 24, 4, 8, $FF00A0FF)
	Circle(48, 48, 12, $FFFF00FF)
StopDrawing()


Counter = 100
Time1 = ElapsedMilliseconds()
For i = 1 To Counter
	CopyImage(0, 1)
	
	ResizeImage(1, 128, 128, #PB_Image_Smooth)
	
Next
Time2 = ElapsedMilliseconds()
For i = 1 To Counter
	CopyImage(0, 2)
	
	ResizeAlphaImage(2, 128, 128, #PB_Image_Smooth)
	
Next
Time3= ElapsedMilliseconds()

; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 600, 600, "ResizeImage", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
  End
EndIf

TextGadget(#PB_Any, 4, 4, 300, 16, "Image original")
ImageGadget(#PB_Any, 4, 20, 64, 64, ImageID(0))
TextGadget(#PB_Any, 4, 144, 300, 16, "Image agrandie : ResizeImage (PB) " + Str(Time2 - Time1) + "ms")
ImageGadget(#PB_Any, 4, 160, 128, 128, ImageID(1))
TextGadget(#PB_Any, 4, 288, 300, 16, "Image agrandie : ResizeAlphaImage " + Str(Time3 - Time2) + "ms")
ImageGadget(#PB_Any, 4, 304, 128, 128, ImageID(2))

Repeat
  Event = WaitWindowEvent()
  
  Select Event
		Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
          
			EndSelect
	EndSelect
  
Until Event = #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)]
dayvid
Messages : 1242
Inscription : mer. 11/nov./2009 18:17
Localisation : Poitiers (Vienne)

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par dayvid »

éffectivement, ya pas photo :P

Bon boulot LSI :)
La vie, C'est comme, Une boitte, De startis, On en voie, De toutes, Les couleurs !

Mon forum http://purebasic.forumphp3.com/index.php
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par Ar-S »

Je le mets au chaud, je le ressortirai si je me remets à la 2D.
Merci
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par blendman »

Un grand merci pour ce code c'est excellent !
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par blendman »

Mince, désolé, je vais casser l'ambiance ^^, mais avec PB 5.30, le code de LSI me donne le même résultat qu'un resizeImage() normal

Code : Tout sélectionner



Enumeration 
  
#ImgOriginal  
#ImgCopy 

EndEnumeration

winw = 400
winh = 300


Procedure ResizeAlphaImage(Image, Width, Height, Quality = #PB_Image_Smooth)
   Protected ID, oWidth, oHeight
   If IsImage(Image)
      oWidth = ImageWidth(Image)
      oHeight = ImageHeight(Image)
      ID = CreateImage(#PB_Any, oWidth, oHeight, 32)
      StartDrawing(ImageOutput(ID))
         Box(0, 0, oWidth, oHeight, $FFFFFF)
         DrawingMode(#PB_2DDrawing_AlphaChannel)
         Box(0, 0, oWidth, oHeight, 0)
         DrawingMode(#PB_2DDrawing_Default)
         DrawAlphaImage(ImageID(Image), 0, 0)
      StopDrawing()
      ResizeImage(ID, Width, Height, #PB_Image_Smooth)
      CopyImage(ID, Image)
      FreeImage(ID)
   EndIf
EndProcedure




OpenWindow(0, 0, 0, winw,winh, "Resize bug", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

w = 100
h = 100

If CreateImage(#ImgOriginal,w,h,32,#PB_Image_Transparent)
  If StartDrawing(ImageOutput(#ImgOriginal))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Circle(w/2,h/2,w/2 -1,RGBA(0,0,0,255))
    StopDrawing()
  EndIf
EndIf

CopyImage(#ImgOriginal,#ImgCopy)
; ResizeImage(#ImgCopy,30,30,#PB_Image_Smooth)
ResizeAlphaImage(#ImgCopy,30,30,#PB_Image_Smooth) ; resultat identique au resizeImage normal ?

; si je décommente cette ligne, ça marche, mais uniquement avec les images ayant une seule couleur ^^. 
; If StartDrawing(ImageOutput(#ImgCopy))
;     DrawingMode(#PB_2DDrawing_AlphaClip)
;     Box(0,0,30,30,RGBA(0,0,0,255))
;     StopDrawing()
;   EndIf


If CanvasGadget(0,0,0,winw,winh)
  If StartDrawing(CanvasOutput(0))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For i = 0 To 20
      DrawAlphaImage(ImageID(#ImgCopy),50+i*5,50+i*7)
    Next i
    StopDrawing()      
  EndIf
EndIf

Repeat
  
  Event = WaitWindowEvent()
    
Until Event = #PB_Event_CloseWindow

G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par G-Rom »

Un resize, quelque soit l'api, pour évité cet "effet de bord" doit être effectué en RAW
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par blendman »

G-Rom a écrit :Un resize, quelque soit l'api, pour évité cet "effet de bord" doit être effectué en RAW
une chose que je ne comprends pas :
quand on resize, logiquement, les pixels en bordure devraient juste changer l'intensité de leur alpha, pas la couleur normalement.

Par exemple, imaginons qu'on pixel du bord soit RGBA(0,255,255,120)
en réduisant, on devrait avoir RGBA(0,255,255,60) par exemple (disons au pixel qui correspond plus ou moins à l'endroit où se trouvait l'autre pixel, en fonction de l'échelle).
là, on a l'impression que le pixel du bord devient RGBA(255,255,255,60), c'est bizarre, ça non ?
Bon, je conçois bien qu'un resize, ce n'est pas une mince affaire, mais si pour tous les autres pixels (internes) ça marche, pourquoi ceux qui sont au bord ou transparent merdouille, on devrait juste avoir un changement d'alpha et pas de couleur. Enfin, pas passer du rouge au blanc en tout cas, éventuellement, une légère modification si on mélange avec les pixels alentours ^^.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par G-Rom »

PB à implémenté l'alpha sur le tard en version 4.x je crois. le resize() à dû être fait en ne prenant pas en compte l'alpha lors du redimensionnement. c'est donc bien resize en smooth qui a un problème.
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par TazNormand »

Hors Sujet désolé, mais j'ai cru un instant que LSI était revenu sur le forum, mais vu que son site n'est plus en ligne et que le domaine est à vendre, je pense qu'il est parti faire autre chose que du dev. :cry:
Image
Image
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Meilleure qualité de ResizeImage avec couche Alpha

Message par blendman »

ah pas cool :(
Il avait fait plein de super code pour les images, j'en utilise quelques uns (grâce à lui, j'ai compris comment gommé l'alpha sur un sprite ou une image)
Répondre