2010-04-08 25 views
7

Ho due file di icone 16x16 RGB/A ICO, ciascuno caricato in un System.Drawing.Icon oggetto separato.Come unire due icone insieme? (Sovrapporre un'icona sopra l'altro)

Come creeresti un nuovo oggetto Icon contenente l'unione delle due icone (una sovrapposta sopra l'altra)?


Edit:
Probabilmente non era troppo chiaro, io non voglio di fondere due immagini le une nelle altre, voglio sovrapporre un'icona sopra l'altro.

Vorrei aggiungere che le icone contengono già parti trasparenti e non hanno bisogno di "blending" trasparente per fare entrambe le icone visibili. Ciò di cui ho bisogno è di sovrapporre i pixel non trasparenti di un'icona sulla parte superiore di un'altra icona. I pixel trasparenti dovrebbero mostrare l'icona di sfondo.

Per esempio, osservare l'icona StackOverflow. Ha alcune aree che sono grigio e arancione e alcune aree che sono totalmente trasparenti. Immagina di voler sovrapporre l'icona SO all'icona di Firefox. Vedresti i grigi e le arance dell'icona SO a colori e, dove l'icona SO è trasparente, vedresti quelle parti dell'icona di Firefox.

+0

Si desidera semplicemente visualizzare il risultato o effettivamente un'altra icona come output? – leppie

+0

Beh alla fine si voglio mostrare il risultato. Ma ho già il modo di visualizzare un oggetto Icon ordinato. Quindi il modo più semplice per me di sovrapporre queste due icone è creare un nuovo oggetto Icon e trasferirlo nel mio sistema esistente. (Non ho bisogno di creare un nuovo file .ico) – demoncodemonkey

risposta

16

Ecco la funzione finale mi è venuta. Era più semplice di quanto pensassi ...
Grazie a Eoin Campbell per aver fatto il duro lavoro.

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

Questo ha funzionato per me ma non al 100%. Ho dovuto specificare le dimensioni di destinazione quando disegno le due immagini in sequenza oppure le disegnava alla loro dimensione originale. Esempio: 'canvas.DrawImage (a, new Rectangle (0, 0, 16, 16));' –

+0

@DavidCarrigan Immagino che entrambe le immagini debbano essere 16x16 altrimenti dovranno essere ritagliate o ridimensionate. Quali dimensioni sono le tue immagini? – demoncodemonkey

+1

Variano quindi è proprio quello che dovevo fare. Praticamente ha aggiunto un altro argomento di un tipo System.Drawing.Size. Questo è stato quindi referenziato per creare la bitmap e specificare una dimensione di destinazione quando si disegnano le due immagini sul canvas. –

7

EDIT

Re: Il tuo commento: Per i principianti ... la mia immagine non sono neri & trasparente. Sono in bianco e nero ... entrambi sono impostati su un'opacità di 0,6f (60%), quindi dove c'è un nero su nero (> 100% nero) o bianco su bianco (> 100% bianco) è bello, ma per le sovrapposizioni avrai il 60% di mix bianco nero che ti darà il colore grigio ... quello che potresti fare è creare 2 ImageAttributes separati e modificare le opacità separatamente per vedere se puoi ottenere l'output previsto (vedi codice modificato). Sarà diverso se le tue immagini hanno sezioni trasparenti.

ha preso un po 'di codice da here

Il trucco è quello di richiamare ogni immagine con una trasparenza in modo che possano essere visti attraverso l'altro. Non specifico per le icone, quindi dovrebbe funzionare per qualsiasi tipo di immagine. Puoi ToBitmap() le tue icone per ottenerle come oggetti di immagine.

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

Grazie, questo è quasi arrivato ma non funziona come mi aspettavo ... nel tuo esempio Output.png non mostra chiaramente alcun insieme di linee. Dove c'è nero su nero, va bene, e dove c'è trasparenza su trasparente, va bene. Ma dove c'è nero su trasparente o viceversa è diventato grigio. Mi aspettavo che fossero griglie nere solide. Ho provato a cambiare la trasparenza ma non ha aiutato ... qualche idea? – demoncodemonkey

+0

aggiornerò leggermente la risposta ... –

+0

Grazie per il tuo aiuto, è risultato più semplice di quanto entrambi pensassimo :) – demoncodemonkey