【问题标题】:How to merge two icons together? (overlay one icon on top of another)如何将两个图标合并在一起? (将一个图标叠加在另一个图标之上)
【发布时间】:2011-02-05 16:27:56
【问题描述】:

我有两个 16x16 RGB/A .ICO 图标文件,每个文件都加载到一个单独的 System.Drawing.Icon 对象中。

您将如何创建一个新的 Icon 对象,其中包含两个图标的合并(一个叠加在另一个图标之上)?


编辑
我可能不太清楚,我不想将两个图像混合在一起,我想将一个图标叠加在另一个图标之上。

我应该补充一点,图标已经包含透明部分,我不需要任何透明的“混合”来使两个图标都可见。我需要将一个图标的不透明像素覆盖在另一个图标的顶部。透明像素应该让背景图标显示出来。

例如,查看 stackoverflow 图标。它有一些区域是灰色和橙色的,还有一些区域是完全透明的。想象一下,您想将 SO 图标覆盖在 Firefox 图标之上。您会看到全彩色的 SO 图标的灰色和橙色,在 SO 图标透明的地方,您会看到 Firefox 图标的这些部分。

【问题讨论】:

  • 您只是想显示结果,还是实际上有另一个图标作为输出?
  • 好吧,最终是的,我想显示结果。但我已经有办法显示排序的 Icon 对象。所以对我来说覆盖这两个图标的最简单方法是创建一个新的 Icon 对象并将其传递到我现有的系统中。 (我不需要制作新的 .ico 文件)

标签: c# image merge icons overlay


【解决方案1】:

这是我想出的最后一个函数。它比我想象的要简单...
感谢 Eoin Campbell 的辛勤工作。

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());
}

【讨论】:

  • 这对我有用,但不是 100% 我必须在连续绘制两个图像时指定目标尺寸,否则它将以原始尺寸绘制它们。示例:canvas.DrawImage(a, new Rectangle(0, 0, 16, 16));
  • @DavidCarrigan 我猜这两个图像都需要为 16x16,否则需要裁剪或调整大小。你的图片尺寸是多少?
  • 它们会有所不同,所以这就是我必须做的。几乎只是添加了另一个 System.Drawing.Size 类型的参数。然后在将两个图像绘制到画布时引用它来创建位图并指定目标大小。
【解决方案2】:

编辑

re:您的评论:首先...我的图像不是黑色和透明的。它们是黑白的……两者都设置为 0.6f (60%) 的不透明度,所以在黑底黑字(>100% 黑色)或白底白字(>100% 白色)的地方看起来不错,但对于重叠您将拥有 60% 的白色黑色混合,为您提供灰色......您可以做的是创建 2 个单独的 ImageAttributes 并单独调整不透明度以查看是否可以获得预期的输出(请参阅更改的代码)。如果您的图片有透明部分,情况会有所不同。

here获取一些代码

诀窍是用透明度绘制每个图像,以便它们可以相互看到。不特定于图标,因此这适用于任何图像类型。您可以先ToBitmap() 您的图标,将它们作为图像对象 afaik。

    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);
    }

【讨论】:

  • 谢谢,这几乎就在那里,但它并没有像我预期的那样工作......在你的例子中,Output.png 没有清楚地显示任何一组行。黑底黑的地方就可以了,透明的地方有透明的就可以了。但是在透明的地方有黑色,反之亦然,它变成了灰色。我希望它始终是纯黑色网格线。我尝试更改透明度,但没有帮助...有什么想法吗?
  • 感谢您的帮助,事实证明它比我们想象的要简单:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 2021-04-08
  • 2022-10-15
  • 2016-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多