[英]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: 从上面的颜色矩阵中,我们得到:
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.