简体   繁体   中英

How to create inverse png image?

i am creating png image which painted on my base, from the base i can save a png image, for your reference

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

this is single color transparency image, now how do i can inverse this image like png filled with any color and the real image portion should be transparent, is there any possibilities?

bit detail : so transparent will go nontransparent and where there is fill will go to transparent

There's a faster way if you're willing to use unsafe code:

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

Note that this doesn't care about the colors and will invert those as well. If you wish to use a specific color, then the code will have to be modified a bit.

EDIT (thanks for Thomas notation)

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

from here : Image Processing in C#: Inverting an image

For anyone who wants a fast method for inverting Bitmap colors without using unsafe:

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 and SetPixel are extremly slow, this method works by copying the Bitmap pixels into a byte array, which you can then loop through and change, before finally copying the pixels back.

When you say invert the transparent sections into color, are you storing the real colors in the PNG image just set to full transparency? A lot of programs will optimize a png by removing the color data from transparency so you can't reverse it.

Colors can be converted to transparency But transparency (without underlying colors) cannot be converted to color.

If your lucky your PNG will be non optimized and still have the original color data intact, but if your doing this from user input then it won't work for a high percentage of cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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