2010-04-08 8 views
7

Mam dwa pliki ikon 16x16 RGB/A .ICO, każdy załadowany do oddzielnego obiektu System.Drawing.Icon.Jak scalić dwie ikony? (nakładka jedna ikona na drugą)

Jak utworzyć nowy obiekt Icon zawierający scalenie dwóch ikon (jednej nałożonej na drugą)?


Edit:
prawdopodobnie nie było zbyt jasne, nie chcę, aby połączyć dwa obrazy do siebie, chcę nałożyć jedną ikonę na drugim.

Należy dodać, że ikony zawierają już przezroczyste części i nie potrzebuję żadnego przezroczystego "mieszania", aby obie ikony były widoczne. Potrzebuję nakładki na nieprzezroczyste piksele jednej ikony nad drugą ikoną. Przezroczyste piksele powinny pokazywać ikonę tła.

Na przykład spójrz na ikonę stackoverflow. Ma pewne obszary, które są szare i pomarańczowe, a niektóre obszary są całkowicie przezroczyste. Wyobraź sobie, że chcesz umieścić ikonę SO na górze ikony Firefox. Zobaczysz szare i pomarańczowe ikony SO w pełnym kolorze, a gdy ikona SO będzie przezroczysta, zobaczysz te części ikony Firefox.

+0

Czy chcesz po prostu wyświetlić wynik, czy też jako wyjście masz inną ikonę? – leppie

+0

W końcu tak, chcę wyświetlić wynik. Ale mam już sposób, aby wyświetlić sortowany obiekt Icon. Tak więc najłatwiejszym sposobem na nałożenie tych dwóch ikon jest utworzenie nowego obiektu Icon i przekazanie go do mojego istniejącego systemu. (Nie muszę tworzyć nowego pliku .ico) – demoncodemonkey

Odpowiedz

16

Oto ostateczna funkcja wymyśliłem. To było prostsze niż myślałem ...
Dzięki Eoin Campbell za wykonanie ciężkiej pracy.

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

To działało dla mnie, ale nie w 100% musiałem określić docelowe wymiary podczas rysowania dwóch obrazów kolejno, bo inaczej narysowałoby je w ich oryginalnym rozmiarze. Przykład: 'canvas.DrawImage (a, nowy Rectangle (0, 0, 16, 16));' –

+0

@DavidCarrigan Myślę, że oba obrazy muszą mieć rozmiar 16x16, w przeciwnym razie będą wymagały przycięcia lub zmiany rozmiaru. Jakie są rozmiary twoich obrazów? – demoncodemonkey

+1

Będą się różnić, więc tak naprawdę to musiałem zrobić. Prawie dodałem kolejny argument typu System.Drawing.Size. Zostało to następnie odniesione do tworzenia bitmapy i określania docelowego rozmiaru podczas rysowania dwóch obrazów na płótnie. –

7

EDIT

Re: Komentarz: Na początek ... mój obraz nie są czarne & przejrzyste. Są czarno-białe ... obie są ustawione na krycie 0,6f (60%), więc tam, gdzie jest czarny na czarnym (> 100% czerni) lub biały na białym (> 100% biały), wygląda to dobrze, ale w przypadku nakładania się będziesz miał 60% białą czarną mieszankę, która daje szary kolor ... możesz zrobić dwa oddzielne ImageAttributes i osobno dostosować nieprzezroczystość, aby zobaczyć, czy możesz uzyskać oczekiwane wyjście (patrz zmieniony kod). Będzie inaczej, jeśli twoje obrazy mają przezroczyste sekcje.

wziął jakiś kod z here

Sztuką jest Draw każdy obraz z przejrzystości, dzięki czemu mogą być one postrzegane przez siebie. Nie dotyczy to ikon, więc powinno to działać dla dowolnego typu obrazu. Możesz najpierw ustawić swoje ikony, aby otrzymać je jako Obiekty Obrazka 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

Dzięki, prawie już istnieje, ale nie działa tak, jak się spodziewałem ... w twoim przykładzie Output.png nie pokazuje wyraźnie żadnego zestawu linii. Gdzie jest czarny na czarnym, jest OK, a gdzie jest przezroczysty na przezroczystym, jest OK. Ale tam, gdzie jest czarny na przezroczystym lub odwrotnie, robi się szary. Spodziewałem się, że będzie to cała czarna linia siatki. Próbowałem zmienić przezroczystość, ale to nie pomogło ... żadnych pomysłów? – demoncodemonkey

+0

Zaktualizuję odpowiedź nieco ... –

+0

Dzięki za pomoc, okazało się, że było prostsze, niż nam się wydawało :) – demoncodemonkey