Zoom améliore avec anti-aliasing

Soyez le premier à donner votre avis sur cette source.

Vue 8 592 fois - Téléchargée 1 116 fois

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

Ajouter un commentaire Commentaires
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
107
Très bien ennixo, voici la méthode que je t'ai donné appliqué à la même image :

http://www.vbfrance.com/code.aspx?ID=28385

Je pense que ca pourra t'être utile moustachu ;)

DarK Sidious
Messages postés
224
Date d'inscription
samedi 25 janvier 2003
Statut
Membre
Dernière intervention
17 juin 2006

je demande a voir =)
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
107
Non ce n'est pas si chaud que cà, il faut utiliser une matrice :
1 0 -1
1 0 -1
1 0 -1

Puis une matrice

1 1 1
0 0 0
-1 -1 -1

Cela trace les contours normalement, et ensuite, il faut appliquer un flou sur les pixels des contours pour obtenir de l'antialiasing.

Note : cette source n'utilise pas de l'antialiasing comme mentionné ci-dessus, mais un filtre de flou uniquement car sur une image zoomé, le tracé des contours est loin d'être bon !

DarK Sidious
Messages postés
224
Date d'inscription
samedi 25 janvier 2003
Statut
Membre
Dernière intervention
17 juin 2006

l'anticrénelage sur une image... sur une bitmap en tt cas c'est compliqué, le programme doit essayer de repérer des formes pour que ce soit efficace, sinon ce sera bizarre et/ou flou... et repérer des formes c'est chaud !!!
Messages postés
1079
Date d'inscription
jeudi 14 novembre 2002
Statut
Membre
Dernière intervention
1 janvier 2012

Un zoom à 1 ? Effectivement, ce n'est pas un Zoom :o)
Je me suis mal exprimé : c'est pour appliquer l'anti aliasing sur une image... sans besoin de l'agrandir. Peut-être existe-t-il d'autres moyens...

Merci de ta réponse

++
Moustachu
Afficher les 21 commentaires

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.