Empiler des images & jouer avec la transparences ? [Résolu]

Signaler
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
-
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
-
Voila mon pb :
Je crée une interface pour un car-pc dont la partie graphique variera selon qu'il fait nuit/jour/crépuscules. Le calculs des heures de lever coucher et crépuscules civils selon la latitude et la longitude, c'est ok ca marche.

Mon problème est de savoir comment empiler une bitmap sur une autre en reglant la transparence de celle du dessus, et utiliser l'image résultante pour repeindre la Form de mon appli.

En gros la form est peinte par defaut avec l'image "Nuit".

-Il fait nuit, l'image "Jour" a un alpha de 0 (totalement transparente, on la voit pas)

-Il fait jour, l'alpha de l'image Jour est a 100% (totalement opaque)

- Aube ou crépuscule, l'alpha varie.

Des idées ?

12 réponses

Messages postés
47
Date d'inscription
mardi 18 mai 2004
Statut
Membre
Dernière intervention
24 juillet 2006

Ce genre de fonction est très lent par rapport au GDI. On peut aussi utiliser des bibliothèques graphiques qui supportent la transparence. En libre/gratuit on trouve GDI+ de Microsoft, en natif dans windowsXP avec un wrapper pour delphi, ou Graphics32.

En restant en GDI la fonction devrait ressembler à ça :

function(canvasNuit, canvasJour: TCanvas; AWidth, AHeight, ATransparency: integer): TBitmap;
var
  bf: BLENDFUNCTION;
begin
  Result := TBitmap.Create;
  Result.Width := AWidth;
  Result.Height := AHeight;
  BitBlt(Result.Canvas, 0, 0, AWidth, AHeight, canvasNuit, 0, 0, SRCCPY);

  bf.BlendOp             := AC_SRC_OVER;
  bf.BlendFlags          := 0;
  bf.SourceConstantAlpha := ATransparency;
  bf.AlphaFormat         := 0;

  AlphaBlend(Result.Canvas, 0, 0, AWidth, AHeight, canvasJour, 0, 0, AWidth, AHeight, bf);
end;
Messages postés
2226
Date d'inscription
dimanche 5 octobre 2003
Statut
Modérateur
Dernière intervention
18 novembre 2010
13
il n'y a pas de canal alpha sur un bitmap, ni sur un TBitmap, disons kil y a une couleur qui sera transparente (la couleur sera celle du pixel du coin inférieur gauche du TBitmap)
au mieux tu auras donc : une bitmap sans transparence (ne pas confondre transparence et alpha), ou une bitmap avec UNE couleur transparente, ou une image invisible (propriété visible := false;)
il existe un code ki gere l'alpha (je ne le connais pas mais il doit exister), il y a peut etres des compos ki gerent ça (j'en cherche pour toi là en ce moment) et sinon euh si je comprends tu veux ensuite recupérer "l'addition des images nuit/jour" pour "repeindre" la form c ça ?
okok bon bah je chch un peu :) bon codage

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient ! ;)

-------------------------------------------
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
C'est exactement ca. L'image "de nuit" a peu de contrast, le tracé des boutons n'est guere visible. Je sais pas comment décrire ca, imagine un autoradio de nuit, on ne voit que le piti truc éclairé au centre du bouton. De jour on voit tout les détails de la façade, le tracé des boutons, etc etc.

Mon but est donc de rajouter ces détails quand il fait jour.
Messages postés
47
Date d'inscription
mardi 18 mai 2004
Statut
Membre
Dernière intervention
24 juillet 2006

La VCL ne sait pas gérer la transparence. Il faut donc appeler directement les fonctions GDI pour faire ce que tu veux.

Regarde la fonction AlphaBlend du GDI.

Bonne chance.
Messages postés
702
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
1 octobre 2009
3
Salut,
Je m'étais intéressé à ce genre de "mélange" d'image en bricolant un écran de veille.
J'avais trouvé un composant (TPictureShow) très complet pour passer d'une image à l'autre.
Pour ton problème il a dans ce composant une fonction qui devrait de convenir (fondu):

// Both bitmaps must be equal size and 32 bit format.
procedure MergeTransparent(dstBitmap, srcBitmap: TBitmap; Transparency: Integer);
var
  dstPixel, srcPixel: PRGBQuad;
  InvertTransparency: Integer;
  bmpWidth, bmpHeight: Integer;
  x, y: Integer;
begin
  bmpWidth := srcBitmap.Width;
  bmpHeight := srcBitmap.Height;
  InvertTransparency := 100 - Transparency;
  for y := 0 to bmpHeight - 1 do
  begin
    srcPixel := srcBitmap.ScanLine[y];
    dstPixel := dstBitmap.ScanLine[y];
    for x := 0 to bmpWidth - 1 do
    begin
      dstPixel^.rgbRed := ((InvertTransparency * dstPixel^.rgbRed) +
                            (Transparency * srcPixel^.rgbRed)) div 100;
      dstPixel^.rgbGreen := ((InvertTransparency * dstPixel^.rgbGreen) +
                              (Transparency * srcPixel^.rgbGreen)) div 100;
      dstPixel^.rgbBlue := ((InvertTransparency * dstPixel^.rgbBlue) +
                             (Transparency * srcPixel^.rgbBlue)) div 100;
      Inc(srcPixel);
      Inc(dstPixel);
    end;
  end;
end;


En gros, il faut tout faire soit même, en utilisant la fonction scanline de chaque bitmap et en faisant son propre mixage pixel par pixel

Ken@vo
____________________
Code, Code, Codec !
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Precision, l'os de la plateforme finale (epia sp) c'est un win98se allégée.
Messages postés
47
Date d'inscription
mardi 18 mai 2004
Statut
Membre
Dernière intervention
24 juillet 2006

La fonction AlphaBlend est supportée par 98.

Pour GDI+ il est possible de télécharger une dll pour 98 sur le site microsoft.

Graphics32 ne requiere rien en particulier, par contre elle est bcps plus performantes quand le processeur dispose du MMX, SSE, ...
Messages postés
47
Date d'inscription
mardi 18 mai 2004
Statut
Membre
Dernière intervention
24 juillet 2006

PS : Pour mon code je viens de voir une erreur :
Dans les appels aux fonctions GDI (BitBlt et AlphaBlend) il faut passer des Canvas.Handle, et non des Canvas.
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Sovitec,
J'ai regardé GDI+, et je ne vois pas comment l'installer. J'ai la dll idoine, tout le toutim downloadé depuis progdigy, mais apres... euh euh pouf pouf pouf comment ca marche ce truc, faut compiler qqch, mettre quoi dans le use ?

Chuis un noob moi, snurfl.
Messages postés
47
Date d'inscription
mardi 18 mai 2004
Statut
Membre
Dernière intervention
24 juillet 2006

Salut,

Pour la dll il suffit de la mettre à un endroit accessible à ton application, comme toute dll. Soit le répertoire de ton application, soit un répertoire faisant parti de ton "PATH" tel que c:\WINDOWS\.

Pour pouvoir l'utiliser depuis delphi il faut installer le wrapper de prodigy, et, dans Tools/Environment options/Library/Libray Path, rajouter le chemin vers le wrapper. Finalement tu peux utiliser les fonctions GDI+ en ajoutant les bonnes unités (GDIPOBJ, GDIPAPI, ...) dans ta clause uses.

Bonne chance.
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
"BitBlt(Result.Canvas.Handle, 0, 0, AWidth, AHeight, canvasNuit.Handle, 0, 0, SRCCPY);"

Ce bout là me pose problème, Delphi7 me dit : Identificateur non déclaré SRCCPY.

La dll est au bon endroit, le "Use" est ok...

Je seche.....
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Bon ben c'est SRCCOPY, et ouala. Pas encore testé, mais ca compile, c'est déja ça.