2010-04-08 21 views
7

J'ai deux fichiers d'icônes 16x16 RVB/A .ICO, chacun chargé dans un objet séparé System.Drawing.Icon.Comment fusionner deux icônes ensemble? (superpose une icône sur l'autre)

Comment créer un nouvel objet Icon contenant la fusion des deux icônes (une superposée l'une sur l'autre)?


Modifier:
Je n'était probablement pas trop clair, je ne veux pas mélanger deux images dans l'autre, je veux superposer une icône sur le dessus d'un autre.

Je devrais ajouter que les icônes contiennent déjà des parties transparentes et que je n'ai pas besoin d'un "fondu" transparent pour rendre les deux icônes visibles. Ce dont j'ai besoin est de superposer les pixels non transparents d'une icône sur le dessus d'une autre icône. Les pixels transparents doivent laisser apparaître l'icône d'arrière-plan.

Par exemple, regardez l'icône stackoverflow. Il y a des zones qui sont grises et orange, et certaines zones qui sont totalement transparentes. Imaginez que vous souhaitiez superposer l'icône SO sur l'icône Firefox. Vous verriez les gris et les oranges de l'icône SO en couleur, et si l'icône SO est transparente, vous verriez les parties de l'icône Firefox.

+0

Voulez-vous simplement afficher le résultat ou avoir une autre icône en sortie? – leppie

+0

Eh bien finalement oui je veux afficher le résultat. Mais j'ai déjà le moyen d'afficher un objet Icon trié. Donc la façon la plus simple pour moi de superposer ces deux icônes est de créer un nouvel objet Icon et de le passer dans mon système existant. (Je n'ai pas besoin de faire un nouveau fichier .ico) – demoncodemonkey

Répondre

16

est ici la fonction finale je suis venu avec. C'était plus simple que je ne le pensais ...
Merci à Eoin Campbell d'avoir travaillé dur.

public Icon AddIconOverlay(Icon originalIcon, Icon overlay) 
{ 
    Image a = originalIcon.ToBitmap(); 
    Image b = overlay.ToBitmap(); 
    Bitmap bitmap = new Bitmap(16, 16); 
    Graphics canvas = Graphics.FromImage(bitmap); 
    canvas.DrawImage(a, new Point(0, 0)); 
    canvas.DrawImage(b, new Point(0, 0)); 
    canvas.Save(); 
    return Icon.FromHandle(bitmap.GetHicon()); 
} 
+1

Cela a fonctionné pour moi mais pas 100% J'ai dû spécifier les dimensions de destination lors du dessin des deux images consécutives ou bien il les dessinerait à leur taille d'origine. Exemple: 'canvas.DrawImage (a, new Rectangle (0, 0, 16, 16));' –

+0

@DavidCarrigan Je suppose que les deux images doivent être 16x16 sinon elles devront être rognées ou redimensionnées. Quelles tailles sont vos images? – demoncodemonkey

+1

Ils varieraient donc c'est vraiment ce que je devais faire. À peu près juste ajouté un autre argument d'un type System.Drawing.Size. Cela a ensuite été référencé pour créer le bitmap et spécifier une taille de destination lors du dessin des deux images sur le canevas. –

7

EDIT

re: votre commentaire: Pour commencer ... mon image ne sont pas noir & transparent. Ils sont en noir et blanc ... les deux sont réglés sur une opacité de 0.6f (60%) donc là où il y a un noir sur noir (> 100% noir) ou blanc sur blanc (> 100% blanc) ça va bien, mais pour les chevauchements vous aurez 60% de mélange noir blanc qui vous donne la couleur grise ... ce que vous pouvez faire est de créer 2 ImageAttributes séparés et de modifier les opacités séparément pour voir si vous pouvez obtenir la sortie attendue (voir code altéré). Ce sera différemment si vos images ont des sections transparentes.

a pris un certain code de here

L'astuce est de dessiner chaque image avec une transparence afin qu'ils puissent être vus à travers l'autre. Non spécifique aux icônes, cela devrait fonctionner pour n'importe quel type d'image. Vous pouvez d'abord utiliser vos icônes pour les obtenir en tant qu'objets d'image.

Merged & Overlaid

using(Image a = Image.FromFile("1.png")) 
    using(Image b = Image.FromFile("2.png")) 
    using (var bitmap = new Bitmap(200, 200)) 
    using (var canvas = Graphics.FromImage(bitmap)) 
    { 
     Rectangle r = new Rectangle(new Point(0, 0), new Size(200, 200)); 
     ColorMatrix cmxPic = new ColorMatrix(); 
      cmxPic.Matrix33 = 1.0f; 

      ImageAttributes iaPic = new ImageAttributes(); 
      iaPic.SetColorMatrix(cmxPic, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 

      ColorMatrix cmxPic2 = new ColorMatrix(); 
      cmxPic2.Matrix33 = 0.5f; 

      ImageAttributes iaPic2 = new ImageAttributes(); 
      iaPic2.SetColorMatrix(cmxPic2, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 


      canvas.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      canvas.DrawImage(a, r, 0, 0, 200, 200, GraphicsUnit.Pixel, iaPic); 
      canvas.DrawImage(b, r, 0, 0, 200, 200, GraphicsUnit.Pixel, iaPic2); 
     canvas.Save(); 

     bitmap.Save("output.png", ImageFormat.Png); 
    } 
+0

Merci, c'est presque là mais ça ne marche pas tout à fait comme je m'y attendais ... dans votre exemple le Output.png ne montre pas clairement l'ensemble des lignes. Là où il y a du noir sur noir, ça va, et là où il y a du transparent sur transparent, c'est OK. Mais là où il y a du noir sur transparent ou vice versa, il devient gris. Je m'attendais à ce qu'il y ait un quadrillage noir solide partout. J'ai essayé de changer la transparence mais ça n'a pas aidé ... des idées? – demoncodemonkey

+0

Je vais mettre à jour la réponse légèrement ... –

+0

Merci pour votre aide, il s'est avéré que c'était plus simple que nous pensions tous les deux :) – demoncodemonkey