2010-04-08 45 views
7

Tengo dos archivos de ícono .ICO RGB/A de 16x16, cada uno cargado en un objeto separado System.Drawing.Icon.¿Cómo combinar dos íconos? (superposición de un ícono encima de otro)

¿Cómo crearía un nuevo objeto Icon que contuviera la combinación de los dos iconos (uno superpuesto uno encima del otro)?


Editar:
que probablemente no era muy claro, no quiero mezclar dos imágenes entre sí, quiero superponer un icono en la parte superior de la otra.

Debo añadir que los iconos ya contienen partes transparentes y no necesito ninguna "combinación" transparente para hacer visibles ambos iconos. Lo que necesito es superponer los píxeles no transparentes de un icono en la parte superior de otro ícono. Los píxeles transparentes deberían dejar ver el ícono de fondo.

Por ejemplo, mire el icono de stackoverflow. Tiene algunas áreas que son de color gris y naranja, y algunas áreas que son totalmente transparentes. Imagine que desea superponer el ícono SO en la parte superior del ícono de Firefox. Vería los grises y las naranjas del ícono SO a todo color, y cuando el ícono SO sea transparente, verá esas partes del ícono de Firefox.

+0

¿Simplemente desea mostrar el resultado o tener otro ícono como salida? – leppie

+0

Bien eventualmente sí Quiero mostrar el resultado. Pero ya tengo la manera de mostrar un objeto Icon ordenado. Así que la manera más fácil para mí de superponer estos dos iconos es crear un nuevo objeto Icon y pasarlo a mi sistema existente. (No necesito hacer un nuevo archivo .ico) – demoncodemonkey

Respuesta

16

Aquí está la última función que se me ocurrió. Era más simple de lo que pensaba ...
Gracias a Eoin Campbell por hacer el trabajo duro.

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

Esto funcionó para mí pero no al 100% Tuve que especificar las dimensiones de destino al dibujar las dos imágenes consecutivamente o de lo contrario las dibujaría en su tamaño original. Ejemplo: 'canvas.DrawImage (a, new Rectangle (0, 0, 16, 16));' –

+0

@DavidCarrigan Supongo que ambas imágenes deben ser 16x16; de lo contrario, deberán recortarse o redimensionarse. ¿De qué tamaño son tus imágenes? – demoncodemonkey

+1

Variarían así que eso es realmente lo que tuve que hacer. Casi acaba de agregar otro argumento de tipo System.Drawing.Size. A continuación, se hizo referencia a este para crear el mapa de bits y especificar un tamaño de destino al dibujar las dos imágenes en el lienzo. –

7

EDITAR

re: su comentario: Para empezar ... mi imagen no son & negro transparente. Son en blanco y negro ... ambos están configurados en 0.6f (60%) de opacidad así que cuando hay un negro sobre negro (> 100% negro) o blanco sobre blanco (> 100% blanco) se ve bien, pero para las superposiciones tendrás un 60% de mezcla de blanco y negro que te dará el color Gris ... lo que podrías hacer es crear 2 ImageAttributes separados y ajustar las opacidades por separado para ver si puedes obtener el resultado esperado (ver código alterado). Será diferente si tus imágenes tienen secciones transparentes.

tomó algo de código de here

El truco es dibujar cada imagen con una transparencia para que puedan verse a través de uno al otro. No es específico para los íconos así que esto debería funcionar para cualquier tipo de imagen. Puede ToBitmap() sus iconos primero para obtenerlos como objetos de imagen afaik.

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

Gracias, casi está por llegar pero no funciona como esperaba ... en su ejemplo Output.png no muestra ningún conjunto de líneas claramente. Donde hay negro sobre negro, está bien, y donde hay transparencia en transparente, está bien. Pero donde hay negro en transparente o viceversa, se vuelve gris. Esperaba que fuera una grilla negra sólida en todo momento. Traté de cambiar la transparencia, pero no ayudó ... ¿Alguna idea? – demoncodemonkey

+0

Actualizaré la respuesta ligeramente ... –

+0

Gracias por su ayuda, resultó que era más simple de lo que pensamos :) – demoncodemonkey

Cuestiones relacionadas