Zoom améliore avec anti-aliasing

Description

Je n'ai pas trouvé qu'équivalent sur ce site donc j'en profite pour poster cette source.

Il s'agit de faire un zoom sur une image, mais en essayant d'éviter l'effet de pixélisation qui en resulte. Bien entendu, les pixels affichés ne correspondent pas à un zoom de chaque pixel, mais sont la somme des pixels avoisinant + le pixel courant le tout divisé par 5.

Cela donne un effet de flou, et atténue l'effet de pixélisation.

Pour voir l'effet, regardez la capture : l'image du haut est obtenue grâce à ma méthode, et l'image du bas est obtenue avec la fonction PaintPicture qui étire bêtement les pixels et qui donne au final une image très pixélisée.

J'utilise bien entendu ma classe de gestion d'image pour les manipulations ce qui permet d'obtenir des affichages quasi instantannée.

Source / Exemple :


Private Sub cmdZoom_Click(Index As Integer)

'déclaration des variables privées
Dim oGestionImageSrc As New CGestionImage
Dim oGestionImageDest As New CGestionImage
Dim iFor1 As Integer 'stocke les valeurs de la boucle For->Next
Dim iFor2 As Integer 'stocke les valeurs de la boucle For->Next
Dim iZoom As Integer 'stocke le rapport du zoom
Dim dZoomIndexX As Double 'stocke l'index du zoom lors du parcours sur X
Dim dZoomIndexY As Double 'stocke l'index du zoom lors du parcours sur Y
Dim iZoomIndexX As Integer 'stocke l'index entier du zoom lors du parcourt sur X
Dim iZoomIndexY As Integer 'stocke l'index entier du zoom lors du parcourt sur Y
Dim iBleu As Byte 'stocke la composante bleue à récupèrer
Dim iVert As Byte 'stocke la composante verte à récupèrer
Dim iRouge As Byte 'stocke la composante rouge à récupèrer
Dim iBleuCouleur As Double 'stocke la composante bleue à appliquer
Dim iVertCouleur As Double 'stocke la composante verte à appliquer
Dim iRougeCouleur As Double 'stocke la composante rouge à appliquer

    'on définit le rapport du zoom
    Let iZoom = Choose(Index, 2, 4, 8)

    'on force le picturebox de destination à être de la bonne taille
    Let pctDest.Width = pctSource.Width * iZoom
    Let pctDest.Height = pctSource.Height * iZoom
    Let pctDest2.Width = pctSource.Width * iZoom
    Let pctDest2.Height = pctSource.Height * iZoom
 
    'on définit les contrôles sources et destination
    Set oGestionImageSrc.PictureBox = pctSource
    Set oGestionImageDest.PictureBox = pctDest

    'on parcourt les pixels 1 ) 1 et on les agrandit avec une moyenne des pixels alentours
    For iFor1 = 0 To pctDest.ScaleWidth
    
        For iFor2 = 0 To pctDest.ScaleHeight
        
            'on définit l'index du zoom sur X et Y
            Let dZoomIndexX = iFor1 / iZoom
            Let dZoomIndexY = iFor2 / iZoom
            Let iZoomIndexX = dZoomIndexX
            Let iZoomIndexY = dZoomIndexY
            
            'on définit la couleur du pixel courant à partir de la couleur courante
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX, dZoomIndexY, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleu * 2
            Let iVertCouleur = iVert * 2
            Let iRougeCouleur = iRouge * 2
        
            'mais aussi des couleurs alentours avec moyenne de toutes les couleurs
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX - 1, (dZoomIndexY), iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * ((iZoomIndexX + 1) - dZoomIndexX))
            Let iVertCouleur = iVertCouleur + (iVert * ((iZoomIndexX + 1) - dZoomIndexX))
            Let iRougeCouleur = iRougeCouleur + (iRouge * ((iZoomIndexX + 1) - dZoomIndexX))
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX + 1, dZoomIndexY, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * (dZoomIndexX - iZoomIndexX))
            Let iVertCouleur = iVertCouleur + (iVert * (dZoomIndexX - iZoomIndexX))
            Let iRougeCouleur = iRougeCouleur + (iRouge * (dZoomIndexX - iZoomIndexX))
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX, dZoomIndexY - 1, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * ((iZoomIndexY + 1) - dZoomIndexY))
            Let iVertCouleur = iVertCouleur + (iVert * ((iZoomIndexY + 1) - dZoomIndexY))
            Let iRougeCouleur = iRougeCouleur + (iRouge * ((iZoomIndexY + 1) - dZoomIndexY))
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX, dZoomIndexY + 1, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * (dZoomIndexY - iZoomIndexY))
            Let iVertCouleur = iVertCouleur + (iVert * (dZoomIndexY - iZoomIndexY))
            Let iRougeCouleur = iRougeCouleur + (iRouge * (dZoomIndexY - iZoomIndexY))

            'on prend aussi en compte les pixels en diagonales en tenant compte de la distance
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX - 1, dZoomIndexY - 1, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * ((iZoomIndexX + 1) - dZoomIndexX)) * (Sqr(2) / 2)
            Let iVertCouleur = iVertCouleur + (iVert * ((iZoomIndexX + 1) - dZoomIndexX)) * (Sqr(2) / 2)
            Let iRougeCouleur = iRougeCouleur + (iRouge * ((iZoomIndexX + 1) - dZoomIndexX)) * (Sqr(2) / 2)
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX + 1, dZoomIndexY - 1, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * (dZoomIndexX - iZoomIndexX)) * (Sqr(2) / 2)
            Let iVertCouleur = iVertCouleur + (iVert * (dZoomIndexX - iZoomIndexX)) * (Sqr(2) / 2)
            Let iRougeCouleur = iRougeCouleur + (iRouge * (dZoomIndexX - iZoomIndexX)) * (Sqr(2) / 2)
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX - 1, dZoomIndexY + 1, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * ((iZoomIndexY + 1) - dZoomIndexY)) * (Sqr(2) / 2)
            Let iVertCouleur = iVertCouleur + (iVert * ((iZoomIndexY + 1) - dZoomIndexY)) * (Sqr(2) / 2)
            Let iRougeCouleur = iRougeCouleur + (iRouge * ((iZoomIndexY + 1) - dZoomIndexY)) * (Sqr(2) / 2)
            Call oGestionImageSrc.GetPixelRGB(dZoomIndexX + 1, dZoomIndexY + 1, iRouge, iVert, iBleu)
            Let iBleuCouleur = iBleuCouleur + (iBleu * (dZoomIndexY - iZoomIndexY)) * (Sqr(2) / 2)
            Let iVertCouleur = iVertCouleur + (iVert * (dZoomIndexY - iZoomIndexY)) * (Sqr(2) / 2)
            Let iRougeCouleur = iRougeCouleur + (iRouge * (dZoomIndexY - iZoomIndexY)) * (Sqr(2) / 2)
            
            Let iBleuCouleur = iBleuCouleur / (4 + Sqr(2))
            Let iVertCouleur = iVertCouleur / (4 + Sqr(2))
            Let iRougeCouleur = iRougeCouleur / (4 + Sqr(2))
            If iBleuCouleur > 255 Then Let iBleuCouleur = 255
            If iVertCouleur > 255 Then Let iVertCouleur = 255
            If iRougeCouleur > 255 Then Let iRougeCouleur = 255
            If iBleuCouleur < 0 Then Let iBleuCouleur = 0
            If iVertCouleur < 0 Then Let iVertCouleur = 0
            If iRougeCouleur < 0 Then Let iRougeCouleur = 0
            
            Call oGestionImageDest.SetPixelRGB(iFor1, iFor2, iRougeCouleur, iVertCouleur, iBleuCouleur)
            
        Next iFor2
        
    Next iFor1
    
    Call oGestionImageDest.Refresh
    
    'on compare avec Paintpicture :
    pctDest2.PaintPicture pctSource, 0, 0, pctSource.ScaleWidth * iZoom, pctSource.ScaleHeight * iZoom, 0, 0, pctSource.ScaleWidth, pctSource.ScaleHeight, vbSrcCopy

End Sub

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.