我有一个二进制图像(来自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?
答案 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)预计Bitmap
为32bpp
张图片,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列计算出来的。绿色是从第二列等计算出来的......