2009-08-27 9 views
8

J'ai créé un bitmap en utilisant GDI +. Je dessine du texte sur ce bitmap en utilisant GDI Drawtext.Using Drawtext je suis incapable d'appliquer la transparence. Toute aide ou code sera apprécié.Transparence au texte dans GDI

+1

Langue préférée? C, C++, VB.net, C# ?? –

+0

Préféré sera simple Windows API/C++ – VideoDev

+1

Est-ce que GDI + une faute de frappe? –

Répondre

13

Si vous souhaitez dessiner du texte sans remplissage d'arrière-plan, SetBkMode(hdc,TRANSPARENT) indiquera à GDI de quitter l'arrière-plan lors du dessin du texte. Pour réellement rendre la couleur de premier plan du texte avec alpha ... va être plus compliquée. GDI ne supporte pas vraiment les canaux alpha dans ses API. En dehors de AlphaBlend tout ce qu'il fait est de préserver le canal. Il n'est en fait pas valide pour définir les bits supérieurs d'un COLOREF à des valeurs alpha car l'octet haut est réellement utilisé pour les indicateurs pour indiquer si le COLOREF est (plutôt qu'une valeur RVB) une entrée de palette.

Donc, malheureusement, votre seul moyen réel est à l'avant:

  1. Créer une DIBSection 32bit. (CreateDIBSection). Cela vous donne un HBITMAP qui est garanti pour être capable de contenir des informations alpha. Si vous créez un bitmap via l'une des autres fonctions de création de bitmap, il s'agira de la couleur de l'appareil qui ne sera peut-être pas 32bpp.
  2. DrawText sur la DIBSection.
  3. Lorsque vous avez créé la DIBSection, vous avez un pointeur vers la mémoire réelle. À ce stade, vous devez parcourir la mémoire et définir les valeurs alpha. Je ne pense pas que DrawText va faire quoi que ce soit à la couche alpha tout seul. Im penser une simple vérification des composants RVB de chaque DWORD de l'image bitmap - si elles sont la couleur forground, réécrire le DWORD avec un alpha de 50% (ou autre) dans l'octet alpha, si elles sont la couleur d'arrière-plan, réécrire avec un 100% alpha dans l'octet alpha. *
  4. AlphaBlend le bitmap sur la destination finale. AlphaBlend nécessite la pré-multiplication du canal alpha dans la source.

* Il pourrait être suffisant pour Memset simplement le DIBSection avec 50% d'alpha avant de faire le DrawText, et veiller à ce que le BkColor est noir. Cependant, je ne sais pas ce que DrawText pourrait faire pour le canal alpha. Certaines expérimentations sont nécessaires.

+0

Merci pour votre réponse.J'ai utilisé cette méthode.Utilisant cela, le texte est dessiné sur le rectangle de façon transparente.Mais je veux appliquer la transparence (alpha) au texte dessiné qui n'est pas possible en utilisant la méthode SetTextColor. Comme SetTextColor ignore la valeur alpha d'une couleur. J'ai traversé une application qui utilise le bitmap masque pour appliquer la transparence, mais je n'ai pas obtenu les résultats souhaités. et je ne veux pas appliquer la transparence à l'image bitmap, je veux appliquer la transparence au texte dessiné sur le bitmap. Toute aide est appréciée – VideoDev

+0

L'idée est, dessiner sur un bitmap noir, pas un bitmap avec des informations sur lui. Après avoir lu le texte, vous pouvez ensuite scanner le bitmap pour les pixels non noirs et ajuster le canal alpha pour chaque pixel en fonction de sa partie du texte ou non. –

0

Hmmmm - essayant de faire la même chose ici - je me demande - je vois que lorsque vous créez une section dib vous spécifiez les "masques" qui sont un masque R, G, B (et alpha). Si c'est vraiment important si cela ne modifie pas vraiment le canal alpha, vous pouvez spécifier le masque différemment pour deux en-têtes bitmap. ONe spécifie thr RVB aux endroits appropriés, l'autre les fait attribuer leurs bits au canal alpha. (Définir la couleur du texte en blanc dans ce cas) puis rendre en deux passes, l'une pour charger les valeurs de couleur, l'autre pour charger les valeurs alpha.

???? de toute façon juste rêvant :)

0

Alors que cette question est de rendre le texte semi-transparent, j'ai eu le problème inverse.

DrawText était rendant le texte dans ma fenêtre en couches (UpdateLayeredWindow) semi-transparent ... et je ne l'ai pas voulu être.

Jetez un oeil à cet autre question ... puisque dans l'autre question je poste un code que vous pourriez facilement modifier ...et est presque exactement ce que Chris Becke suggère dans sa réponse.

7

solution simple et FACILE :)

eu ce problème, j'ai essayé de changer les valeurs alpha et Prémultiplier, mais il y avait un autre problème - les polices lissées et ClearType où non représentés correctement (bords laids). Alors, que je l'ai fait ...

  1. Composez votre scène (bitmaps, graphiques, etc.)
  2. BitBlt rectangle requis de cette scène (même que votre rectangle de texte, de l'endroit où vous voulez que votre texte soit) en mémoire DC avec bitmap compatible sélectionné à 0,0 coordonnées de destination
  3. Dessinez votre texte dans ce rectangle en mémoire DC.
  4. Maintenant AlphaBlend ce rectangle sans AC_SRC_ALPHA dans la BLENDFUNCTION et avec SourceConstantAlpha désirée à partir de cette mémoire DC vers votre scène DC.

Je pense que vous l'avez :)

0

Une réponse limitée à une situation spécifique:

Si vous avez un graphique avec canal alpha et que vous voulez dessiner le texte opaque sur un fond opaque localement, d'abord préparer votre bitmap 32 bits avec des pinceaux 32 bits créés avec CreateDIBPatternBrushPt. Ensuite, parcourez les bits bitmap inversant le canal alpha, dessinez votre texte comme vous le feriez normalement (y compris SetBkMode à TRANSPARENT), puis inversez à nouveau l'alpha dans le bitmap. Vous pouvez ignorer la première inversion si vous inversez l'alpha de vos pinceaux.