Page 1 sur 1

Meilleure qualité de ResizeImage avec couche Alpha

Publié : dim. 22/mai/2011 10:52
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

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : dim. 22/mai/2011 13:02
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

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : lun. 23/mai/2011 12:52
par dayvid
éffectivement, ya pas photo :P

Bon boulot LSI :)

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : lun. 23/mai/2011 14:24
par Ar-S
Je le mets au chaud, je le ressortirai si je me remets à la 2D.
Merci

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : mer. 06/juil./2011 11:51
par blendman
Un grand merci pour ce code c'est excellent !

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : lun. 15/juin/2015 11:45
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


Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : lun. 15/juin/2015 13:37
par G-Rom
Un resize, quelque soit l'api, pour évité cet "effet de bord" doit être effectué en RAW

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : lun. 15/juin/2015 14:18
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 ^^.

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : lun. 15/juin/2015 15:01
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.

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : mar. 16/juin/2015 8:04
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:

Re: Meilleure qualité de ResizeImage avec couche Alpha

Publié : mar. 16/juin/2015 17:52
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)