Remove the black background color of a bitmap

2020-05-06 17:18发布

I need to remove the black background color of a bitmap in C# VS2013.

It is just like that I draw some points on a canvas. The canvas is black and I just need to change the canvas to be transparent meanwhile keeping colorful points on it without any changes.

I got the solution at: How to remove white background color from Bitmap

Bitmap capcha = new Bitmap(@"C:/image.png");
capcha.MakeTransparent(Color.Black);

But, the background still have a gray color like a fog covering the points on the image.

How to remove it ?

UPDATE I used the code:

ImageAttribute imageAttribute = new ImageAttribute();
imageAttribute.SetGamma(0.5f, ColorAdjustType.Bitmap);
gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height),
            0, 0, img.Width, img.Height,    GraphicsUnit.Pixel, imageAttribute );

I got same thing.

More update of C# code to draw an image :

 System.Drawing.Bitmap canvasImage = new System.Drawing.Bitmap(xSize, ySize, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 canvasImage.MakeTransparent(Color.Black);
 Graphics g = Graphics.FromImage(canvasImage);
 System.Drawing.Bitmap tempImage = myDrawImageFunction(myPoints);
 g.Clear(Color.Transparent);  // this only give me an empty image without any points on it. But, if I uncomment it, I will have an  image with black background.
 // my understanding about g.DrawImage() is to draw points on tempImage
 //  after clearing the background. But, the image still have a foggy covering on the image.
 g.DrawImage(tempImage, new System.Drawing.PointF(x_position, y_position));

I want to have a transparent background for "tempImage" before any points are drawn on it.

The example image has a back ground that needs to be removed but the colorful points on the image need to be kept without any changes.

image with the black background that needs to be removed but the colorful points need to be kept.

1条回答
聊天终结者
2楼-- · 2020-05-06 17:44

This will do the job:

public Color MakeTransparent(Color c, int threshold)
{   // calculate the weighed brightness:
    byte val = (byte)((c.R * 0.299f + c.G * 0.587f + c.B * 0.114f));
    return val < threshold ?  Color.FromArgb(0, c.R, c.G, c.B) : c;
}

You could use it in a double loop over the pixels, but for fast results you should call it from the code in this post (second part!) which uses LockBits.

Change this

ModifyHue hueChanger = new ModifyHue(MaxChannel);

to the new function:

ModifyHue hueChanger = new ModifyHue(MakeTransparent);

and call it with a suitable threshold, maybe 10 or 20..:

c = hueChanger(c, 20); 

The function skips the call to the system's MakeTransparent function and directly sets the alpha channel of each pixel to 0.

If you want to create a uniform color instead of a transparent one it should be easy to modify (e.g. by returning Color.FromArgb(255, 0, 0, 0) for solid black)

Do note that, while the code in the linked post takes both 24 and 32 bbp formats you should definitely not save as JPG, as this will re-introduce artifacts and the result will not work well with e.g. a TransparencyKey color..

Instead do save it as PNG, as Hans suggests!

I hope you can modify the button code to a function :-)

查看更多
登录 后发表回答