IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[C#] Manipulation d'images importante


Sujet :

Windows Forms

  1. #1
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut [C#] Manipulation d'images importante
    Bonjour,

    Après pas mal de recherche et d'échec, je suis toujours confronté à un problème. La GDI+ est trop lente. Je souhaite effectuer un rognage sur une image dont les dimensions sont importantes (>7000px de largeur). Passer par un Graphics prend énormément de temps. Voilà une démonstration pour mieux comprendre le problème. Cliquer sur le bouton pour vous déplacer le vers coin inférieure-droit de la carte. Quel autre moyen simple en C# pourrait combler cette lenteur ?

    Merci

    Doug

  2. #2
    Membre confirmé
    Profil pro
    Ingénieur de développement
    Inscrit en
    Avril 2005
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur de développement

    Informations forums :
    Inscription : Avril 2005
    Messages : 169
    Par défaut
    Bonjour.

    Je n'arrive pas à faire fonctionner ton exemple. Une fenêtre avec un label en haut à gauche, un bouton en bas à droite. Une erreur se produit lorsqu'on clique sur le bouton. Donc je ne sais pas ce que fais ton exemple.

    Je fais beaucoup de traitement d'images, et comme pour toi, le C# (ou plutôt le coté managé) ne nous vient pas en aide, bien au contraire.
    Pour la vitesse, 1 seule solution : les pointeurs et les adresses.
    Donc, beaucoup de code "unsafe" et rapatriement des fonctions Win32 de copie de mémoire.

    Je n'ai pas trouvé d'autres solutions !

  3. #3
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    Le programme récupère une portion de la carte et l'affiche dans la fenêtre. Cela permet de se déplacer sur sa carte comme c'est le cas sur mappy, viamichelin, etc...

    J'avais commencé à m'intéresser au côté non managé via les pointeurs en essayant de faire pointer chaque pixel de l'image que j'affiche vers le pixel correspondant de la grosse image(carte). J'ai du mal m'y prendre.

    Tu aurais une idée en code non managé pour récupéré une portion d'image ?

  4. #4
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Citation Envoyé par Doug_
    J'avais commencé à m'intéresser au côté non managé via les pointeurs
    Oui le code unsafe est imperial en Image Processing avec C# tu gagneras beaucoup de performance tu vas voir !!

    Voici un lien qui m'a beaucoup permis d'avancer :Image Processing Lab in C#

    Bon courage

  5. #5
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    Citation Envoyé par mehdi_tn
    Voici un lien qui m'a beaucoup permis d'avancer :Image Processing Lab in C#
    Merci pour le lien.
    Ce programme est une vrai usine à gaz.
    Dans mon cas, c'est très simple, il me faut juste récupérer une image pour ensuite effectuer quelque surcharge par dessus et afficher le résultat toutes les x milisecondes.

  6. #6
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Citation Envoyé par Doug_
    effectuer quelque surcharge
    Qu'est-ce qu'une surcharge en Imagerie ?

  7. #7
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    Surcharger en ce sens que je vais rajouter du text par dessus, etc etc

  8. #8
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Rajouter un text c'est simple, il y a des methodes pour ca : Drawing Text with GDI+. Le probleme se pose dans ton cas lors de l'application de Filtres, rendre l'image en noir et blanc, iterer sur les pixels, dans ce cas il vaut mieux utiliser du code Unsafe

  9. #9
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    Disons que mon problème est de trouver un moyen très rapide pour récupérer la portion d'image provenant de la grande image. Ensuite ce sera facile d'écrire par dessus avec la GDI+ comme tu le dis.Le problème reste entier.

  10. #10
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Pourquoi tu veux recuperer la portion d'image ?

    Pourquoi ne pas specifier juste l'emplacement sur l'image?

  11. #11
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    Y a t'il moyen de le faire sans les Graphics ?
    Je dois effectuer la manip plusieurs fois par seconde.

  12. #12
    Membre Expert Avatar de Mose
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 143
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 143
    Par défaut
    Un petit lien pour multiplier tes perfs par dix au niveau traitement d'image
    Voir la partie 1.5.
    On y parle des méthodes LockBits/UnlockBits et des propriétés Stride et Scan0

  13. #13
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Citation Envoyé par Doug_
    Y a t'il moyen de le faire sans les Graphics ?
    Je dois effectuer la manip plusieurs fois par seconde.
    Oui tu peux parcourir tes pixels en mode unsafe. Mais ca depends toujours de ton besoin. Si tu veux ecrire un text dans un endroit precis alors il vaut mieux utiliser les methodes du framework avec le Graphics

  14. #14
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    N'étant toujours parvenu a régler le problème, je reviens vous voir.

    Afin de mieux comprendre le problème, voici ce que j'essai de faire.
    Un GPS. Je dispose donc de ma carte (7000 px * 3000 px) dont je veux récupérer une petite partie (celle qui est visible vis à vis de la taille de la fenêtre). Comme dis précédemment, passer par des graphics et pas très rapide.

    La solution est donc de passer par du code non managé ?
    Comment prendre le problème par le bon bout ?
    J'ai un peu peur des pointeurs ...

  15. #15
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Citation Envoyé par Doug_
    J'ai un peu peur des pointeurs ...
    N'aie pas peur, n'aie pas peur . C'est tres simple.

    Je t'ai preparé un petit code pour extraire une zone d'une image, j'ai repris une partie de code de ce projet image Processing lab in C# , et je l'ai modifié et ajouté quelques fonctionnalités :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     
    //pointX et pointY : Abcisse et Ordonné de l'angle haut, gauche de la zone à extraire
            //w : width de la zone à extraire
            //h : height de la zone à extraire 
    public static Bitmap ExtraireImage(Bitmap srcImg,int pointX, int pointY, int w, int h)
            {
                const short R = 2;
                const short G = 1;
                const short B = 0;
     
                // get source image size
                int width = srcImg.Width;
                int height = srcImg.Height;
     
                //Verifier les parametres.
                if ((pointX + w) > width || (pointY + h) > height)
                    throw new ArgumentException();
     
                PixelFormat srcFmt = (srcImg.PixelFormat == PixelFormat.Format8bppIndexed) ?
                    PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb;
     
                // lock source bitmap data
                BitmapData srcData = srcImg.LockBits(
                    new Rectangle(0, 0, width, height),
                    ImageLockMode.ReadOnly, srcFmt);
     
                Bitmap dstImg = (srcFmt == PixelFormat.Format8bppIndexed) ?
        CreateGrayscaleImage(w, h) :
        new Bitmap(w, h, srcFmt);
     
                // lock destination bitmap data
                BitmapData dstData = dstImg.LockBits(
                    new Rectangle(0, 0, w, h),
                    ImageLockMode.ReadWrite, srcFmt);
     
                int srcOffset = srcData.Stride - ((srcFmt == PixelFormat.Format8bppIndexed) ? width : width * 3);
                int dstOffset = dstData.Stride - ((srcFmt == PixelFormat.Format8bppIndexed) ? w : w * 3);
     
                // do the job
                unsafe
                {
                    byte* src = (byte*)srcData.Scan0.ToPointer();
                    byte* dst = (byte*)dstData.Scan0.ToPointer();
     
     
     
                    if (srcFmt == PixelFormat.Format8bppIndexed)
                    {
     
                          //positionner le curseur sur l'angle PointX, PointY
                        src += pointY * (width + srcOffset)+pointX;
     
                        for (int y = 0; y < h; y++)
                        {
                            for (int x = 0; x < w; x++, src++, dst++)
                            {
                                *dst = *src;
                            }
                            //positionner le curseur sur la ligne suivante
                            src += srcOffset + width - w;
                            dst += dstOffset;
                        }
                    }
                    else
                    {
                        //positionner le curseur sur l'angle PointX, PointY
                        src += pointY * (3* width + srcOffset) + 3*pointX;
     
                        for (int y = 0; y < h; y++)
                        {
                            for (int x = 0; x < w; x++, src += 3, dst += 3)
                            {
                                dst[B] = src[B];
                                dst[G] = src[G];
                                dst[R] = src[R];
     
                            }
                            //positionner le curseur sur la ligne suivante
                            src += srcOffset + 3 * (width - w);
                            dst += dstOffset;
                        }
                    }
                }
                // unlock both images
                dstImg.UnlockBits(dstData);
                srcImg.UnlockBits(srcData);
     
                return dstImg;
            }
     
        public static Bitmap CreateGrayscaleImage(int width, int height)
            {
                // create new image
                Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
                // set palette to grayscale
                SetGrayscalePalette(bmp);
                // return new image
                return bmp;
            }
      public static void SetGrayscalePalette(Bitmap srcImg)
            {
                // check pixel format
                if (srcImg.PixelFormat != PixelFormat.Format8bppIndexed)
                    throw new ArgumentException();
     
                // get palette
                ColorPalette cp = srcImg.Palette;
                // init palette
                for (int i = 0; i < 256; i++)
                {
                    cp.Entries[i] = Color.FromArgb(i, i, i);
                }
                // set palette back
                srcImg.Palette = cp;
            }


    Voila j'espere que tu pourras avancer, n'hesite pas à poser des questions si tu ne comprends pas quelque chose.

  16. #16
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 22
    Par défaut
    Merci Medhi, ca marche mieu (plus vite).

  17. #17
    Membre Expert
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Par défaut
    Ah enfin des nouvelles, je me demandais ou tu étais passé .

    Content de t'avoir aidé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Manipulation d'images
    Par Tragnee dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 08/04/2006, 17h59
  2. [VBA-E]Manipuler des images
    Par nils.angot dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 14/02/2006, 10h59
  3. [SWING] Manipulation d'images
    Par TylerKnoxx dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 13/09/2005, 22h33
  4. [SDL] manipulation d'image
    Par zdra dans le forum OpenGL
    Réponses: 4
    Dernier message: 28/02/2004, 16h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo