C#从二进制图像获取透明位图

时间:2015-02-13 14:39:29

标签: c# bitmap emgucv

我有一个二进制图像(来自EMGU)A我希望得到一个透明的位图,其中A是黑色,到处都是透明的红色,其中A是白色。一开始我想至少让黑色部分看不见,已经失败了:

我尝试通过以下方式这样做:

private Graphics graphics;
private Bitmap bitmap;
private Image<Gray, Byte> mask;

//graphic, bitmap and mask are being initialized in the constructor of the object
public Bitmap getMask()
{
    //...
    graphics.clear(Color.FromArgb(0,0,0,0);
    graphics.DrawImage(mask.ToBitmap(), 0, 0);
    bitmap.makeTransparent(255, 0, 0, 0);

    //...
}

如何使用白色到红色 - 部分? 是否有更容易/更有效的方法可以使用EMGU?

2 个答案:

答案 0 :(得分:1)

这是一个快速的例行程序,应该按照你的要求进行:

    public static Bitmap MakeSpecialTransparent(Bitmap bmp)
    {
        // we expect a 32bpp bitmap!
        var bmpData = bmp.LockBits(
                                new Rectangle(0, 0, bmp.Width, bmp.Height),
                                ImageLockMode.ReadWrite, bmp.PixelFormat);

        long len = bmpData.Height * bmpData.Stride;
        byte[] data = new byte[len];
        Marshal.Copy(bmpData.Scan0, data, 0, data.Length);

        for (int i = 0; i < len; i += 4)
        {
            if (data[i] == 0  && data[i+1] == 0  && data[i+2] == 0  )
            {
                data[i] = 0; data[i + 1] = 0; data[i + 2] = 0; data[i + 3] = 0;
            }
            else
            if (data[i] == 255  && data[i+1] == 255  && data[i+2] == 255  )
            {
                data[i] = 0; data[i + 1] = 0; data[i + 2] = 255; data[i + 3] = 0;
            }

        }
        Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
        bmp.UnlockBits(bmpData);
        return bmp;
    }

请注意,a)预计Bitmap32bpp张图片,b)没有容差:如果黑色&amp;白色像素不是 100%黑色&amp;白色他们不会改变。

另请注意,我们在此处理的物理像素是有序的BGRA,因此data[i+3]是Alpha频道,data[i+2]Red等。

要添加容差,您可能需要学习linked post

答案 1 :(得分:1)

作为锁定位和一次操作一个像素的替代方法(这无疑是更快),您还可以使用颜色转换矩阵来实现相同的效果。矩阵方法相当灵活,原始图像不一定是完美的;如果原始图像有噪声,这种方法仍然有效。

针对您的具体情况(黑色=&gt;透明,白色=&gt;红色/ 50%),代码如下所示:

using System.Drawing;
using System.Drawimg.Imaging;
...
// Original image to be transformed
var src = Image.FromFile(@"c:\temp\test.png");

// Destination image to receive the transformation
var dest = new Bitmap(src.Width, src.Height, PixelFormat.32bppArgb);

using (var g = Graphics.FromImage(dest))
{
    var attr = new ImageAttributes();
    float[][] matElements = {
        new float[] { 0.0f, 0.0f, 0.0f, 0.5f, 0.0f },
        new float[] { 0.0f, -1.0f, 0.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 0.0f,  0.0f, 0.0f, 0.0f },
        new float[] { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }
    };

    attr.SetColorMatrix(new ColorMatrix(matElements), ColorMatrixFlag.Default,
        ColorAdjustType.Bitmap);
    g.DrawImage(src, new Rectangle(0, 0, src.Width, src.Height), 0, 0,
        src.Width, src.Height, GraphicsUnit.Pixel, attr);
}

从上面的颜色矩阵我们得到:

  • 新红色值= 1
  • 新绿色值= 1 - 旧绿色值
  • 新蓝色值= 1 - 旧蓝色值
  • 新的alpha值= 0.5 *旧的红色值

新的红色值是从矩阵的第1列计算出来的。绿色是从第二列等计算出来的......