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

SDL Discussion :

Stéganographie de deux images


Sujet :

SDL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Par défaut Stéganographie de deux images
    Voila je désire réaliser une petite application qui réalise une stéganographie ( qui cache une image dans une autre image ). J'avais pour cela pensé au raisonnement:

    - On prend un pixel ( le premier, puis les suivants grace a une boucle ) de l'image support et celui de l'image a cacher, on transforme son code de couleur en binaire ( exemple: 176 => 10110000 )

    - On prend les quatres bits de poids fort du code de couleur du pixel de l'image de base, on vire les quatres bits de poids faible du pixel de l'image a cacher, et on les remplace par les bits de poids fort du code de couleur du pixel de l'image a cacher. Je ne suis pas assez clair ? Voila un exemple ( je n'ai pas les bons termes, apprenez m'en ):

    Image support: Rouge: 176 => 10110000
    Vert: 96 => 01100000
    Bleu: 208 => 11010000

    Image a cacher: Rouge: 80 => 01010000
    Vert: 192 => 11000000
    Bleu: 224 => 11100000

    Apres la steganographie: Rouge => 10110101 => 181
    Vert => 01101100 => 108
    Bleu => 11011110 => 222
    Ainsi, l'image de base ( support ) n'a quasiment aucune différence de couleur par rapport a l'image finale ( entre l'image support et l'image finale, il y a une différence de 4 entre les deux rouges, soit une différence imperceptible a l'oeil nu ).

    J'avais pour ce faire pensé a utiliser ces fonctions:

    Code : 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
     
    /* ********************************************************************* */
    /*obtenirPixel : permet de récupérer la couleur d'un pixel
    Paramètres d'entrée/sortie :
    SDL_Surface *surface : la surface sur laquelle on va récupérer la couleur d'un pixel
    int x : la coordonnée en x du pixel à récupérer
    int y : la coordonnée en y du pixel à récupérer
     
    Uint32 resultat : la fonction renvoie le pixel aux coordonnées (x,y) dans la surface
    */
    Uint32 obtenirPixel(SDL_Surface *surface, int x, int y)
    {
        /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel.
        En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur
        de l'image : 8, 16, 24 ou 32 bits.*/
        int nbOctetsParPixel = surface->format->BytesPerPixel;
        /* Ici p est l'adresse du pixel que l'on veut connaitre */
        /*surface->pixels contient l'adresse du premier pixel de l'image*/
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
     
        /*Gestion différente suivant le nombre d'octets par pixel de l'image*/
        switch(nbOctetsParPixel)
        {
            case 1:
                return *p;
     
            case 2:
                return *(Uint16 *)p;
     
            case 3:
                /*Suivant l'architecture de la machine*/
                if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
                    return p[0] << 16 | p[1] << 8 | p[2];
                else
                    return p[0] | p[1] << 8 | p[2] << 16;
     
            case 4:
                return *(Uint32 *)p;
     
            /*Ne devrait pas arriver, mais évite les erreurs*/
            default:
                return 0; 
        }
    }
    Code : 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
    /* ********************************************************************* */
    /*definirPixel : permet de modifier la couleur d'un pixel
    Paramètres d'entrée/sortie :
    SDL_Surface *surface : la surface sur laquelle on va modifier la couleur d'un pixel
    int x : la coordonnée en x du pixel à modifier
    int y : la coordonnée en y du pixel à modifier
    Uint32 pixel : le pixel à insérer
    */
    void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
    {
        /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel.
        En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur
        de l'image : 8, 16, 24 ou 32 bits.*/
        int nbOctetsParPixel = surface->format->BytesPerPixel;
        /*Ici p est l'adresse du pixel que l'on veut modifier*/
        /*surface->pixels contient l'adresse du premier pixel de l'image*/
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
     
        /*Gestion différente suivant le nombre d'octets par pixel de l'image*/
        switch(nbOctetsParPixel)
        {
            case 1:
                *p = pixel;
                break;
     
            case 2:
                *(Uint16 *)p = pixel;
                break;
     
            case 3:
                /*Suivant l'architecture de la machine*/
                if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
                {
                    p[0] = (pixel >> 16) & 0xff;
                    p[1] = (pixel >> 8) & 0xff;
                    p[2] = pixel & 0xff;
                }
                else
                {
                    p[0] = pixel & 0xff;
                    p[1] = (pixel >> 8) & 0xff;
                    p[2] = (pixel >> 16) & 0xff;
                }
                break;
     
            case 4:
                *(Uint32 *)p = pixel;
                break;
        }
    }
    Seulement le problème est qu'il me faut des données en binaire, et non en héxadécimal ! De plus, je ne sais pas comment dire au programme de "mélanger" les séries binaires... Pouvez vous m'aider ? Merci.

    Si vous ne voyez toujours pas de quoi je parle, allez ICI

    PS: Pour commencer, j'avais pensé a faire des tests avec des SDL_CreatRGBSurface pour n'avoir qu'une couleur.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Binaire, héxadécimal, ... ce ne sont que des représentations textuelles de la même chose : des nombres entiers. Pas la peine de s'embêter avec ça dans ton programme, garde les différentes bases uniquement pour te représenter dans ta tête ce que tu codes.

    Il te faut trois opérateurs bit-à-bit ici :
    & qui permet de faire un ET bit à bit (pour créer des masques)
    | qui permet de faire un OU bit à bit (pour combiner les bits de deux valeurs)
    >> qui fait un décalage vers la droite, pour ramener les bits de poids fort vers les bits de poids faible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    unsigned char CouleurSupport = 75;
    unsigned char CouleurCachee  = 96;
     
    // On prend les 4 bits de poids fort de la couleur support
    unsigned int BitsPoidsFort = CouleurSupport & 0xF0;
     
    // On prend les 4 bits de poids fort de la couleur cachée, qu'on décale de 4 vers la droite
    unsigned int BitsPoidsFaible = CouleurCachee >> 4;
     
    // On combine les deux
    unsigned int Couleur = BitsPoidsFort | BitsPoidsFaible;

  3. #3
    Membre confirmé Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Par défaut
    Ce que tu m'as montré permet donc de prendre un taux de couleur de deux pixels de deux images, et de faire une manipulation entre les bits de poids faibles/forts. En revanche, est ce que Couleur est utilisable tel quel ? Est il considéré comme un int ? Doit il subir une nouvelle manipulation ?
    Car grace au code que tu m'as donné, je serais en mesure de créer une fonction qui manipule les bits des taux de couleur mais comment relier cette éventuelle fonction aux deux autres que j'ai déjà trouvé ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int Fusion_Tx_Rouge( unsigned char Tx_Rouge_Support, 
                                    unsigned char Tx_Rouge_Image )
    {
     
       unsigned int BitsPoidsFort = Tx_Rouge_Support & 0xF0;
     
       unsigned int BitsPoidsFaible = Tx_Rouge_Image >> 4;
     
       unsigned int Tx_Rouge_Pixel = BitsPoidsFort | BitsPoidsFaible
     
       return Tx_Rouge_Pixel;
    }

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    En fait tu restes sur 8 bits, donc tu peux garder des unsigned char jusqu'à la fin. Voire même des Uint8, si SDL définit ce type (mieux vaut travailler avec des types à taille fixe pour ce genre de choses).

    Ensuite tu peux combiner tes 3 composantes pour former un Uint32 à passer à ta fonction d'écriture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Uint8 Rouge = Fusion_FX(RougeSupport, RougeCache);
    Uint8 Vert  = Fusion_FX(VertSupport,  VertCache);
    Uint8 Bleu  = Fusion_FX(BleuSupport,  BleuCache);
     
    Uint32 CouleurFinale = (Rouge << 16) | (Vert << 8) | Bleu;
    Je crois qu'il vaudrait même mieux utiliser la fonction SDL_MapRGB pour créer un pixel dont le format sera compatible avec celui de ta surface de destination.

  5. #5
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    voici la manipulation sur un pixel. Les fonctions getpixel et putpixel sont dans la doc officielle de SDL et dans la FAQ.

    Code : 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
    Uint32 pixel_support = getpixel(support, 0, 0);
    Uint32 pixel_image = getpixel(image, 0, 0);
     
    Uint8 rouge_support, vert_support, bleu_support;
    Uint8 rouge_image, vert_image, bleu_image;
     
    //On récupère les couleurs
    SDL_GetRGB(pixel_support, support->format, &rouge_support, &vert_support, &bleu_support);
    SDL_GetRGB(pixel_image, image->format, &rouge_image, &vert_image, &bleu_image);
     
    /* maintenant pour chaque couleur on fait l'opération */
    Uint8 bitspoidsfort = rouge_support &0xF0;
    Uint8 bitspoidsfaible = rouge_image >> 4;
    //rouge final
    rouge_support = bitspoidsfort | bitspoidsfaible;
     
    /********************************
      faire la même chose avec le vert et le bleu
     ********************************/
     
    //et on remet le pixel
    pixel_support = SDL_MapRGB(support->format, rouge_support, vert_support, bleu_support);
     
    putpixel(support, 0, 0);
    Ce code utilise celui donné par laurent pour la fusion des pixels ^^

    Edit: grillé

  6. #6
    Membre confirmé Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Par défaut
    Edit: grillé
    ??

    Uint32 pixel_support = getpixel(support, 0, 0);
    Uint32 pixel_image = getpixel(image, 0, 0);

    Uint8 rouge_support, vert_support, bleu_support;
    Uint8 rouge_image, vert_image, bleu_image;

    //On récupère les couleurs
    SDL_GetRGB(pixel_support, support->format, &rouge_support, &vert_support, &bleu_support);
    SDL_GetRGB(pixel_image, image->format, &rouge_image, &vert_image, &bleu_image);

    /* maintenant pour chaque couleur on fait l'opération */
    Uint8 bitspoidsfort = rouge_support &0xF0;
    Uint8 bitspoidsfaible = rouge_image >> 4;
    //rouge final
    rouge_support = bitspoidsfort | bitspoidsfaible;

    /********************************
    faire la même chose avec le vert et le bleu
    ********************************/

    //et on remet le pixel
    pixel_support = SDL_MapRGB(support->format, rouge_support, vert_support, bleu_support);

    putpixel(support, 0, 0);
    Merci

    Ce code utilise celui donné par laurent pour la fusion des pixels ^^
    En effet.

  7. #7
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    ????
    grillé: laurent a posté pendant que j'écrivais mon message, en répondant aussi à ta question

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

Discussions similaires

  1. [ImageMagick] Coller deux images
    Par Todd62 dans le forum Bibliothèques et frameworks
    Réponses: 9
    Dernier message: 27/02/2006, 09h08
  2. [ImageMagick] Générer deux images à partir du même script
    Par molesqualeux dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 07/01/2006, 01h42
  3. [PIL] Difference entre deux images
    Par t_om84 dans le forum Calcul scientifique
    Réponses: 4
    Dernier message: 26/12/2005, 12h45
  4. superposer deux images ?
    Par terminoz dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 20/08/2005, 09h04
  5. Réponses: 10
    Dernier message: 30/06/2005, 12h20

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