Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge two icons together? (overlay one icon on top of another)

I've got two 16x16 RGB/A .ICO icon files, each loaded into a separate System.Drawing.Icon object.

How would you create a new Icon object containing the merge of the two icons (one overlaid on top of the other)?


Edit:
I probably wasn't too clear, I don't want to blend two images into each other, I want to overlay one icon on top of another.

I should add that the icons already contain transparent parts and I do not need any transparent "blending" to make both icons visible. What I need is to overlay the non-transparent pixels of one icon over the top of another icon. The transparent pixels should let the background icon show through.

For example, look at the stackoverflow icon. It has some areas that are grey and orange, and some areas that are totally transparent. Imagine you want to overlay the SO icon on top of the Firefox icon. You would see the greys and oranges of the SO icon in full colour, and where the SO icon is transparent, you would see those parts of the Firefox icon.

like image 211
demoncodemonkey Avatar asked Apr 08 '10 12:04

demoncodemonkey


2 Answers

Here's the final function I came up with. It was simpler than I thought...
Thanks to Eoin Campbell for doing the hard work.

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());
}
like image 117
demoncodemonkey Avatar answered Nov 15 '22 13:11

demoncodemonkey


EDIT

re: your comment: For starters... my image aren't black & transparent. They are black and white... both are set to 0.6f (60%) opacity so where there's a black on black (>100% black) or white on white (>100% white) it's look fine, but for the overlaps you'll have 60% white black mix which gives you the Gray color... what you could do is create 2 seperate ImageAttributes and tweak the opacities seperately to see if you can get the expected output (see altered code). It'll be have differently if your images have transparent sections.

took some code from here

The trick is to Draw each image with a transparency so that they can be seen through each other. Not specific to Icons so this should work for any image type. You can ToBitmap() your icons first to get them as Image Objects 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);
    }
like image 38
Eoin Campbell Avatar answered Nov 15 '22 11:11

Eoin Campbell