Rotation d'image pour le compact framework

Soyez le premier à donner votre avis sur cette source.

Snippet vu 13 913 fois - Téléchargée 16 fois


Contenu du snippet

Bonjour à tous et à toutes!
ceci est juste une petite fonction en C# pour palier à l'absence de méthode de rotation d'image dans le Compact Framework,...
dans un premier temps on va calculer la taille de l'image après rotation puis on applique un couleur d'arrière plan à la nouvelle image (ici on prendra arbitrairement la couleur du pixel (0,0) de l'image d'origine pour couleur d'arrière plan, et enfin on va chercher pour chacun des pixels de l'image finale le pixel correspondant dans l'image d'origine...

Source / Exemple :


public static System.Drawing.Bitmap Rotate(System.Drawing.Bitmap ImageSource, int angle)
{
    //Déclaration des variables utiles à la rotation
    System.Drawing.Bitmap RotatedImage;
    int i;
    int j;
    System.Drawing.Color couleur;
    int mx, my, mxdest, mydest;
    int bx, by;
    double angle_radian;
    double tcos;
    double tsin;
    double largeurdest;
    double hauteurdest;

    //calcul de l'angle en radian, ainsi que du cosinus et sinus de l'angle qui seront utiliser régulièrement
    angle_radian = -angle * Math.PI / 180.0;
    tcos = Math.Cos(angle_radian);
    tsin = Math.Sin(angle_radian);

    //calcul de la taille maximal de l'image après rotation (pour éviter de perdre des "morceaux d'image"
    largeurdest = Math.Ceiling(ImageSource.Width * Math.Abs(tcos) + ImageSource.Height * Math.Abs(tsin));
    hauteurdest = Math.Ceiling(ImageSource.Width * Math.Abs(tsin) + ImageSource.Height * Math.Abs(tcos));

    //Instanciation de l'image finale avec la taille calculer
    RotatedImage = new System.Drawing.Bitmap((int)Math.Ceiling(largeurdest), (int)Math.Ceiling(hauteurdest));

    //Calcul du centre de l'image source et de l'image après rotation (pour recentrer l'image)
    mxdest = RotatedImage.Width / 2;
    mydest = RotatedImage.Height / 2;
    mx = ImageSource.Width / 2;
    my = ImageSource.Height / 2;

    //On applique comme couleur d'arrière plan de notre nouvelle image la couleur du premier pixel de l'image d'origine (arbitraire)
    for (j = 0; j < RotatedImage.Height; j++)
    {
        for (i = 0; i < RotatedImage.Width; i++)
        {
            RotatedImage.SetPixel(i, j, ImageSource.GetPixel(0, 0));
        }
    }

    //rotation de l'image
    for (j = 0; j < RotatedImage.Height; j++)
    {
        for (i = 0; i < RotatedImage.Width; i++)
        {
            //On recherche les coordonnées du pixel i,j de la nouvelle image dans l'image source
            bx = (int)(Math.Ceiling(tcos * (i - mxdest) + tsin * (j - mydest) + mx));
            by = (int)(Math.Ceiling(-tsin * (i - mxdest) + tcos * (j - mydest) + my));
            if (bx >= 0 && bx < ImageSource.Width && by >= 0 && by < ImageSource.Height)
            {
                //On récupère la couleur du pixel bx,by de l'image source
                couleur = ImageSource.GetPixel(bx, by);
                
                //On recopie la couleur trouver dans le pixel correspondant
                RotatedImage.SetPixel(i, j, couleur);
            }
        }
    }
    return RotatedImage;
}

Conclusion :


Ce code source est optimisable je pense mais en tout cas il est fonctionnel, n'ésitez pas à me signaler les éventuelles difficultés pour faire fonctionner ce code...
Attention ce code n'a pas pour prétention de faire mieux que les méthode éxistantes dans le Framework 2.0 complet mais juste de pallier à l'absence de ces méthodes dans le CompactFramework...

A voir également

Ajouter un commentaire

Commentaires

Messages postés
12
Date d'inscription
vendredi 10 octobre 2008
Statut
Membre
Dernière intervention
9 février 2010

Je veux pas trop m'avancer mais un petit coup de lockbit pourrais te faire gagner pas mal de performance
A+
Messages postés
2
Date d'inscription
mardi 3 juillet 2007
Statut
Membre
Dernière intervention
12 juin 2008

salut,
Merci beaucoup pour votre reponse rapide ^^, ca resoud le probeleme.
Messages postés
65
Date d'inscription
mercredi 18 avril 2007
Statut
Membre
Dernière intervention
12 juin 2008
1
Salut,
de mémoire, l'image contenue dans une pictureBox est au format System.Drawing.Image, l'erreur viens donc tout simplement du fait que l'image que tu passe en paramètre à la méthode n'est pas dans le bon format,... Si l'image que tu place dans ta pictureBox est au format System.Drawing.Bitmap essaye ceci sa devrait fonctionner :
pict.Image = Rotate((System.Drawing.Bitmap)pict.Image, 20);

Bon courage...
Messages postés
2
Date d'inscription
mardi 3 juillet 2007
Statut
Membre
Dernière intervention
12 juin 2008

salut,
dabor je voulais vous remercier pour ce code, et je voulais savoir est ce que pour appeler cette fonction faut juste metre l'image dans dans un pictureBox (pict par exemple) et definir l'angle par exemple 20°,puis faire
pict.Image = Rotate(pict.Image, 20)
Si c'est le cas, en faisant ca j'obtient cette erreur:"The best overloaded method match for 'monprojet.Rotate(System.Drawing.Bitmap, int)' has some invalid arguments"
d'apres ce que j'ai compris le probleme reside dont la synthaxe que j'ai utiliser poru appeler la fonction...
j'attends vos reponses
merci.
Messages postés
65
Date d'inscription
mercredi 18 avril 2007
Statut
Membre
Dernière intervention
12 juin 2008
1
Bonjour!
J'ai mis au point cette méthode pour faire des rotations de petites images (moin de 30 pixels sur 30 pixels) donc cela ne me pose pas de problèmes mais éffectivement la rotation peut devenir très lente mais cela dépend non seulement des Get/SetPixel mais aussi de l'angle de rotation choisi,...
Pour ce qui est d'améliorer ce code on peut éssayer d'autre méthode en passant par des pointeurs (ce qui implique de vérrouiller en mémoire l'image d'abord pour éviter qu'elle ne soit déplacée en mémoire) mais ce n'est pas le but ici puisque ma fonction à pour but de proposer une fonction simple et haut niveau donc facilement compréhensible par des débutants par exemple,...
Afficher les 11 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.