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 :

SDL_SetColorKey, plusieurs transparence ?


Sujet :

SDL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Points : 30
    Points
    30
    Par défaut SDL_SetColorKey, plusieurs transparence ?
    Bonjour a tous

    J'arrive sans problème a rendre une couleur transparente, mais par contre quand j'essaye d'en mettre une 2eme ça ne marche pas ....


    Si par exemple je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        image = IMG_Load("test.jpg");
        SDL_SetColorKey(image, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 0, 0, 0));
    Pas de soucis la couleur noire disparait. Mais si je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        image = IMG_Load("test.jpg");
        SDL_SetColorKey(image, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 0, 0, 0));
        SDL_SetColorKey(image, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 1, 1, 1));
    La couleur noire réapparait, et ce n'est que la 2eme couleur qui est transparente... Y a-t-il une solution pour rendre plusieurs couleurs transparente en même temps ?

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Points : 622
    Points
    622
    Par défaut
    color_key ne marche qu'avec une couleur si je ne me trompe pas.

    je peut te proposer une solution "system D" a défault de connaitre un autre moyen, toute fois je n'ai pas tester cette solution :

    si tu veux que les couleurs transparente soit le blanc et le noir
    - tu applique le color_key avec le noir sur l'image
    - tu blit sur une surface blanche
    - tu applique le color_key blanc sur cette surface
    - tu la blit sur la surface destination (l'écran par exemple)

    je pense que ça doit marcher... a vérifier. après ce n'est surement pas le meilleur moyen de faire ça, peut être même le pire

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    C'est la solution que j'ai utilisé, mais je l'ai trouvé un peu brut...

  4. #4
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Sinon tu fais du pixel par pixel en rendant transparents ceux que tu veux, mais à mon avis c'est plus lent

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    je suis débutant, je ne sais pas encore manipuler les pixel, juste des surfaces pour l'instant.

    Quelques explications ? ou liens ?

  6. #6
    Membre habitué Avatar de Polyfructol
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2007
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2007
    Messages : 131
    Points : 157
    Points
    157
    Par défaut
    Plusieurs choses :

    Je trouve cela bizarre que tu ais 2 couleurs à rendre transparente. Utilise un éditeur d'image et rend tes 2 zones transparentes de la même couleur.

    Aussi, tu utilises du JPEG, qui est un format avec perte de qualité, et donc les zones de couleurs transparentes risques d'être altérées à la sauvegarde. Notamment les contours de ces zones. En fait quand on utilise SDL_SetColorKey() on connait exactement la valeur de la couleur et donc on utilise un format d'image sans perte de qualité.


    Sinon, si tu veux une transparence plus lisse, tu devrais trouver ton compte en te servant de la composante alpha (en utilisant un format d'image tel PNG ou TGA (sans perte de qualité ceux-ci)). Plus besoin à ce moment là de SetColorKey. Juste en faisant "IMG_Load("test.png");" ton image sera rendue transparente. (c'est même plus facile pour un débutant)

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    C'est justement le problème lié au contour que je rencontre, il est vrai que la plus part des sprites sont en .gif ou .png (et la évidemment pas de problème), mais j'en ai quelques unes en .jpg et là ça se corse.

    J'ai finalement fait un petit bout de code qui me permet de balayer une certaine gamme de couleurs, mais c'est assez lent...

    Dernière petite question, pour la météo ils utilise un blue screen, mais cet écran ne peut pas être d'une seule couleur, même s'il est peint correctement l'éclairage ne peut pas être parfait. Juste par curiosité quelqu'un sait quel est le traitement informatique derrière la caméra ?

  8. #8
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 327
    Points
    2 327
    Par défaut
    Meme avis que polyFructol.

    Si tu dois définir deux couleur de transparence, c'est qu'il y a un probleme.

    Pour ton probleme de jpg, la solution est simple. Il suffit d'ouvrir une nouvelle image en bmp avec les meme dimension, de copier/coller ton image dedans et d'enregistrer. Ainsi, ton jpg est devenue bmp et ne subi pas de perte de donné.

    Pour la manipulation pixel :

    C'est relativement simple. Il faut parcourir toute ta SDL_Surface pixel par pixel. Tu recupere la couleur du pixel et selon cette couluer, tu blit oui ou non ce pixel.

    Pour recuperer la couleur, la SDL fourni via la doc la fonction :
    Uint32 getpixel(SDL_Surface *surface, int x, int y)


    Ca donne ceci :

    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
     
    SDL_Surface *Image = SDL_LoadBMP("Une image.bmp");
    int i, j;
    for (i=0 ; i<imageAsteroid->w ; i++)
        for (j=0 ; j<imageAsteroid->h ; j++)
        {
            int couleurPixel = getpixel(Image, i, j);
            if ((couleurPixel != COULEUR1) && (couleurPixel != COULEUR))
            {
                Rect pixel, positionPixel;
                    pixel.x = i;
                    pixel.y = j;
                    pixel.w = 1;
                    pixel.h = 1;
                    positionPixel.x = 250 + i;
                    positionPixel.y = 120 + j;
     
                SDL_BlitSurface (Image, &pixel, SDl_GetVideoSurface(), &positionPixel);
            }
        }
    Attention, pour l'avoir tester, je peux affirmer que cela est TRES LENT !!
    Pour une image de 40x40 pixel, tu appelle 1600 fois SDL_BlitSurface, 1600 fois getpixel ....

    Pour Uint32 getpixel(SDL_Surface *surface, int x, int y)
    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
     
    /*
     * Return the pixel value at (x, y)
     * NOTE: The surface must be locked before calling this!
     */
    Uint32 getpixel(SDL_Surface *surface, int x, int y)
    {
        int bpp = surface->format->BytesPerPixel;
        /* Here p is the address to the pixel we want to retrieve */
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
     
        switch(bpp) {
        case 1:
            return *p;
     
        case 2:
            return *(Uint16 *)p;
     
        case 3:
            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;
     
        default:
            return 0;       /* shouldn't happen, but avoids warnings */
        }
    }


    Poue le blue screen, je doit t'avouer que je ne sais pas reellement; mais a mon avis, toute les couleurs proche d'un certains blue son rendu transparente. Ils doivent donc avoir definie une "fourchette" mais je sais pas comment.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    En tous cas merci pour les réponses

    Citation Envoyé par SofEvans Voir le message
    Poue le blue screen, je doit t'avouer que je ne sais pas reellement; mais a mon avis, toute les couleurs proche d'un certains blue son rendu transparente. Ils doivent donc avoir definie une "fourchette" mais je sais pas comment.
    Ce qui me titille le plus c'est qu'ils font ça en temps réel.

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Points : 622
    Points
    622
    Par défaut
    a mon avis nos amis de la météo n'utilisent pas SDL...

    pour ton problème d'artefact sur tes jpg, il m'est arrivé de passer des heures (j'exagère peut être un peu, quoi que...) à supprimer tout ces artefacts d'une image jpeg pour pouvoir l'enregistrer en bmp et avoir une image propre...

    après peut être que tu pourrais créer un programme auquel tu donne une image jpg + une couleur de transparence et qui te supprimes les pixels dont la couleur est proche de la couleur transparente puis l'enregistre au format png...

  11. #11
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 327
    Points
    2 327
    Par défaut
    Citation Envoyé par Jackyzgood Voir le message
    En tous cas merci pour les réponses



    Ce qui me titille le plus c'est qu'ils font ça en temps réel.
    Hum, c'est pas dit qu'ils le fasse en temps reel. Je ne sais pas vraiment si c'est en temps reel, mais de toutes facon, l'image tele peut etre reduit a une image d'un tel nombre de pixel en largeur et tel nombre de pixel en hauteur. avec la puissance des machine, ca doit pas etre compliqué de supprimer une couleur en temps réel.

    Mais bon, je m'avance alors que je ne fais que supposer.

    Citation Envoyé par bebaijhi
    après peut être que tu pourrais créer un programme auquel tu donne une image jpg + une couleur de transparence et qui te supprimes les pixels dont la couleur est proche de la couleur transparente puis l'enregistre au format png...

    Citation Envoyé par Jackyzgood
    C'est justement le problème lié au contour que je rencontre, il est vrai que la plus part des sprites sont en .gif ou .png (et la évidemment pas de problème), mais j'en ai quelques unes en .jpg et là ça se corse.

    J'ai finalement fait un petit bout de code qui me permet de balayer une certaine gamme de couleurs, mais c'est assez lent...
    Il l'a deja fait apparement. Par contre, je ne comprend pas pourquoi tu dis que c'est lent. Tu balaye ta gamme de couleur, a chaque fois que tu as une couleur dans la gamme que tu desire rendre transparente, tu met la couleur de ton pixel a la couleur exact de transparence. Tu fais une fois ca et tu utilise SDL_SaveBMP(TonImage,"Image apres.bmp"); et puis voila, tu as une image au format bmp avec une seule et unique couleur de transparence.

  12. #12
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 826
    Points : 218 287
    Points
    218 287
    Billets dans le blog
    117
    Par défaut
    Pour la météo ( question super intéressante ), je pense que c'est possible de le faire en temps réel ( pas avec la SDL :p ).
    Prenez GIMP ( logiciel de dessin "équivalent" de photoshop mais libre ( et gratuit ) ). Il a une option qui permet la sélection par couleur ( très pratique :p ). Celle ci est en plus réglable. On peut donc réglé le seuil de tolérance. Ceci permet de demander à selectionner la seulement couleur sur laquelle on a cliqué, ou à selectionner toute les couleurs proche de celle ci. Il le fait très rapidement.

    De plus, nos PCs sont capable d'afficher 60 image par secondes dans les jeux, pour avoir des effets de lumière / d'ombres, de textures ... de machin, de trucs, alors que la météo demande juste de prendre touts les pixels d'une certaine couleur ( avec le seuil qu'ils veulent ) et de remplacer ceci par une couleur situé dans une texture ( ou alors calculé un peu à l'avance ( possibilité d'animation ). De plus, on pourrait aussi garder la luminosité de la couleur de base, pour pouvoir remettre l'ombre sur la carte que l'on vient d'appliquer par informatique \o/.

    Sinon, pardon, je répond pas du tout à la question :p
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  13. #13
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Moi je dis que si on veut avoir des performances il faut utiliser openGL, attendre la nouvelle version de SDL ou au moins correctement optimiser son code

    Déjà prendre les options de compilations qui font que le code va le plus vite possible, ensuite trouver le bon algorithme! Regarder dans le code source de la SDL comment ils font peut être très instructif, de même que dans SDL_gfx, ...

    Pour faire un traitement de toute une surface, ne pas faire un getpixel à chaque fois et pas de blit avec des rectangle qui font un pixel de large!

    Il faut par exemple créer une nouvelle surface de même dimension, parcourir pixel à pixel:

    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
     
    /* on suppose qu'on est sur 32 bits */
    Uint32 * px_pointer =     (Uint32 *)surface->pixels;
    Uint32 * px_pointer2 =     (Uint32 *)surface2->pixels;
    Uint32 numpixels = surface->w * surface->h;
     
    /* ne pas oublier de faire le test du lock de la surface */
    while (numpixels > 0)
    {
        if (*px_pointer = couleur1 || *px_pointer = couleur2)
           *px_pointer2 = couleur_transparente;
        else
           *px_pointer2 = *px_pointer;
     
        px_pointer++;
        px_pointer2++;
        numpixels--;
    }
     
    /* ne pas oublier de faire le test d'unlock de la surface */
    PS: désolé pour le nommage des variables qui est un peu chaotique!

Discussions similaires

  1. [GD] Fusionner plusieurs PNG transparents et en faire un JPG
    Par Sayrus dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 06/02/2013, 15h57
  2. Plusieurs PictureBox et transparence
    Par Moustico dans le forum C#
    Réponses: 4
    Dernier message: 02/04/2010, 19h37
  3. Un label transparent avec plusieurs lignes
    Par bvsud dans le forum Composants VCL
    Réponses: 10
    Dernier message: 09/02/2010, 17h23
  4. Transparence plusieurs objets
    Par romainromain dans le forum OpenGL
    Réponses: 5
    Dernier message: 30/07/2009, 14h29
  5. Shortcut avec plusieurs touches
    Par scorpiwolf dans le forum C++Builder
    Réponses: 4
    Dernier message: 06/07/2002, 16h57

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