【问题标题】:How to render an image with a color-keyed green mask in C#?如何在 C# 中使用颜色键控的绿色蒙版渲染图像?
【发布时间】:2014-01-22 22:14:22
【问题描述】:

试图找出在 C# 中以特定颜色的遮罩呈现图像的最优雅的方法(通过 System.Drawing 或可在桌面和 ASP.NET 应用程序中使用的等效方法)。

蒙版图像将包含应该“绘制”图像的绿色键。

(下面的预期结果图像并不完美,手套索...)

【问题讨论】:

    标签: c# mask imaging system.drawing.imaging


    【解决方案1】:

    为此有多种技术:

    1. 扫描像素数据并构建掩码图像(如 itsme86 和 Moby Disk 所建议的那样)

    2. 一种扫描变体,它从蒙版构建一个剪切区域并在绘图时使用该区域(请参阅 Bob Powell 的 this article

    3. Graphics.DrawImage 调用中使用颜色键进行屏蔽。

    我将专注于第三个选项。

    假设您要从蒙版中消除的图像颜色是Color.Lime,我们可以使用ImageAttributes.SetColorKey 来阻止在调用Graphics.DrawImage 期间绘制任何该颜色,如下所示:

    using (Image background = Bitmap.FromFile("tree.png"))
    using (Image masksource = Bitmap.FromFile("mask.png"))
    using (var imgattr = new ImageAttributes())
    {
        // set color key to Lime 
        imgattr.SetColorKey(Color.Lime, Color.Lime);
    
        // Draw non-lime portions of mask onto original
        using (var g = Graphics.FromImage(background))
        {
            g.DrawImage(
                masksource,
                new Rectangle(0, 0, masksource.Width, masksource.Height),
                0, 0, masksource.Width, masksource.Height,
                GraphicsUnit.Pixel, imgattr
            );
        }
    
        // Do something with the composited image here...
        background.Save("Composited.png");
    }
    

    结果:

    如果您想将树的这些部分放入另一个图像中,您可以使用相同的技术(在Color.Fuchsia 上使用颜色键)。

    【讨论】:

    • 真棒又直截了当。我在这里看到的唯一缺陷(我应该在问题中解决)是如果我想要一个透明背景而不是 Fuschia,它会在 Lime 区域和透明区域内绘制图像,对吗?
    • 如果空蒙版区域(示例蒙版中的紫红色区域)是透明的,那么您将需要不同的方法。您可以将遮罩绘制到紫红色背景上以获取上面的遮罩,然后将上面的输出颜色键控到透明位图上 - 基本上是一个额外的颜色键操作。对于小位图,最好构建一个剪切区域 - 请参阅我在答案中链接的 Bob Powell 的文章。
    【解决方案2】:

    你想要这样的东西:

    Bitmap original = new Bitmap(@"tree.jpg");
    Bitmap mask = new Bitmap(@"mask.jpg");
    
    int width = original.Width;
    int height = original.Height;
    
    // This is the color that will be replaced in the mask
    Color key = Color.FromArgb(0,255,0);
    
    // Processing one pixel at a time is slow, but easy to understand
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            // Is this pixel "green" ?
            if (mask.GetPixel(x,y) == key)
            {
                // Copy the pixel color from the original
                Color c = original.GetPixel(x,y);
    
                // Into the mask
                mask.SetPixel(x,y,c);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可能会读入掩码并将其转换为图像,当像素为绿色时,alpha 通道设置为 0,当像素为任何其他颜色时,alpha 通道设置为 0xFF。然后您可以在原始图像上绘制蒙版图像。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-03
        • 2015-07-09
        • 2023-03-04
        • 1970-01-01
        • 2014-03-18
        • 2011-10-28
        • 2021-12-26
        • 1970-01-01
        相关资源
        最近更新 更多