简体   繁体   English

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

[英]C# get from binary Image to transparent Bitmap

I got a binary Image(from EMGU) A and I want to get out a bitmap that is transparent everywhere where A is black and a transparent red everywhere, where A is white. 我有一个二进制图像(来自EMGU)A,我想得到一个位图,该位图在A为黑色的任何地方都是透明的,而在A为白色的任何地方都是透明的。 For the beginning I wanted to at least make the black part invisible, which already failed: 首先,我想至少使黑色部分不可见,但已经失败了:

I tried to do so by the following: 我尝试通过以下方法做到这一点:

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

    //...
}

how do I do it with the white to red - part? 我该如何处理白色到红色的部分? is there a easier/more efficient way to do it maybe by using EMGU? 是否有可能通过使用EMGU来实现这一目的的更简单/更有效的方法?

Here is a fast routine that should do what you asked for: 这是一个快速的例程,应该可以满足您的要求:

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

Note that this a) expects the Bitmap to come as 32bpp images and b) does not have any tolerance : If the black & white pixels are not 100% black & white they will not be changed. 请注意,这a)期望Bitmap 32bpp图像,并且b)没有32bpp :如果黑白像素不是100%黑白,则它们将不会更改。

Also note that the physical pixels we address here, are ordered BGRA , so data[i+3 ] is the Alpha channel, data[i+2] is Red etc.. 还要注意,我们在此处寻址的物理像素是有序的BGRA ,因此data[i+3 ]是Alpha通道, data[i+2]Red等。

To add tolerance you may want to study the linked post ! 要增加容忍度,您可能需要研究链接的帖子

As an alternative to locking the bits and manipulating pixels one at a time (which is admittedly faster), you could also use a color transformation matrix to achieve the same affect. 作为一次锁定位和操纵像素的一种替代方法(公认的更快),您还可以使用颜色转换矩阵来实现相同的效果。 The matrix approach is fairly flexible, and your original image doesn't have to be perfect; 矩阵方法相当灵活,您的原始图像不一定是完美的。 this approach still works if the original image is noisy. 如果原始图像有噪点,此方法仍然有效。

For your specific case (black => transparent, white => red/50%) the code would look like this: 对于您的特定情况(黑色=>透明,白色=>红色/ 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);
}

From the color matrix above we get: 从上面的颜色矩阵中,我们得到:

  • New red value = 1 新红色值= 1
  • New green value = 1 - old green value 新绿色值= 1-旧绿色值
  • New blue value = 1 - old blue value 新蓝色值= 1-旧蓝色值
  • New alpha value = 0.5 * old red value 新的alpha值= 0.5 *旧的红色值

The new red value is calculated from the 1st column in the matrix. 新的红色值是从矩阵的第一列计算得出的。 Green is calculated from the 2nd column, etc... 绿色是从第二列计算出来的,依此类推...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM