4

我正在创建在我的底座上绘制的 png 图像,从底座我可以保存一个 png 图像,供您参考

Graphics g = e.Graphics;
 ....
g.DrawLine(pen, new Point(x, y), new Point(x1, y1));
 .....
base.OnPaint(e);

using (var bmp = new Bitmap(500, 50))
{
    base.DrawToBitmap(bmp, new Rectangle(0, 0, 500, 50));
    bmp.Save(outPath);
}

这是单色透明图像,现在我如何反转这个图像,比如填充任何颜色的 png,真实图像部分应该是透明的,有没有可能?

位细节:所以透明将变为不透明,有填充的地方将变为透明

4

4 回答 4

7

如果您愿意使用unsafe代码,还有一种更快的方法:

private unsafe void Invert(Bitmap bmp)
{
    int w = bmp.Width, h = bmp.Height;
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

    int* bytes = (int*)data.Scan0;
    for ( int i = w*h-1; i >= 0; i-- )
        bytes[i] = ~bytes[i];
    bmp.UnlockBits(data);
}

请注意,这不关心颜色,也会反转这些颜色。如果您希望使用特定的颜色,则必须对代码进行一些修改。

于 2012-07-11T08:58:01.483 回答
6

编辑 (感谢托马斯符号)

public void ApplyInvert()  
{  
    byte A, R, G, B;  
    Color pixelColor;  

    for (int y = 0; y < bitmapImage.Height; y++)  
    {  
        for (int x = 0; x < bitmapImage.Width; x++)  
        {  
            pixelColor = bitmapImage.GetPixel(x, y);  
            A = (byte)(255 - pixelColor.A); 
            R = pixelColor.R;  
            G = pixelColor.G;  
            B = pixelColor.B;  
            bitmapImage.SetPixel(x, y, Color.FromArgb((int)A, (int)R, (int)G, (int)B));  
        }  
    }  
}

从这里开始:C#中的图像处理:反转图像

于 2012-07-11T08:48:08.457 回答
6

对于任何想要一种快速方法来反转位图颜色而不使用不安全的人:

public static void BitmapInvertColors(Bitmap bitmapImage)
{
    var bitmapRead   = bitmapImage.LockBits(new Rectangle(0, 0, bitmapImage.Width, bitmapImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
    var bitmapLength = bitmapRead.Stride * bitmapRead.Height;
    var bitmapBGRA   = new byte[bitmapLength];
    Marshal.Copy(bitmapRead.Scan0, bitmapBGRA, 0, bitmapLength);
    bitmapImage.UnlockBits(bitmapRead);

    for (int i = 0; i < bitmapLength; i += 4)
    {
        bitmapBGRA[i]     = (byte)(255 - bitmapBGRA[i]);
        bitmapBGRA[i + 1] = (byte)(255 - bitmapBGRA[i + 1]);
        bitmapBGRA[i + 2] = (byte)(255 - bitmapBGRA[i + 2]);
        //        [i + 3] = ALPHA.
    }

    var bitmapWrite = bitmapImage.LockBits(new Rectangle(0, 0, bitmapImage.Width, bitmapImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb);
    Marshal.Copy(bitmapBGRA, 0, bitmapWrite.Scan0, bitmapLength);
    bitmapImage.UnlockBits(bitmapWrite);
}

Bitmap GetPixel 和 SetPixel 非常慢,此方法通过将 Bitmap 像素复制到字节数组中来工作,然后您可以循环并更改,最后再将像素复制回来。

于 2014-06-23T23:32:19.677 回答
0

当您说将透明部分反转为颜色时,您是否将真实颜色存储在刚刚设置为完全透明的 PNG 图像中?许多程序会通过从透明度中删除颜色数据来优化 png,这样您就无法反转它。

颜色可以转换为透明度但透明度(没有基础颜色)不能转换为颜色。

如果幸运的话,您的 PNG 将未经优化,并且仍然具有完整的原始颜色数据,但如果您从用户输入中执行此操作,那么它在大部分情况下都不起作用。

于 2012-07-11T09:51:42.360 回答