C# 反转图像返回黑色图像

C# 反转图像返回黑色图像,c#,.net,image-processing,gdi+,C#,.net,Image Processing,Gdi+,我想反转一个图像对象。当前我的代码如下所示: private Image Invert(Image img) { var bmpPicture = new Bitmap(img.Width, img.Height); var iaPicture = new ImageAttributes(); var cmPicture = new ColorMatrix { Matrix00 = -1, Matrix11 = -1, Matrix

我想反转一个图像对象。当前我的代码如下所示:

    private Image Invert(Image img)
    {
        var bmpPicture = new Bitmap(img.Width, img.Height);
        var iaPicture = new ImageAttributes();
        var cmPicture = new ColorMatrix { Matrix00 = -1, Matrix11 = -1, Matrix22 = -1 };
        iaPicture.SetColorMatrix(cmPicture);
        var gfxPicture = Graphics.FromImage(img);
        var rctPicture = new Rectangle(0, 0, img.Width, img.Height);
        gfxPicture.DrawImage(img, rctPicture, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, iaPicture);
        return bmpPicture;
    }

但是,当我运行此命令并在
图片框中显示它时,结果是一个黑色图像。我在VisualStudio2012的Windows8版本预览下运行这个。如果有更好的方法,请告诉我。谢谢。

通过反转,你的意思是创建一个负片吗?如果是,这里有一个片段:

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 = pixelColor.A;
            R = (byte)(255 - pixelColor.R);
            G = (byte)(255 - pixelColor.G);
            B = (byte)(255 - pixelColor.B);
            bitmapImage.SetPixel(x, y, Color.FromArgb((int)A, (int)R, (int)G, (int)B));
        }
    }

}
public void ApplyInvert()
{
字节A、R、G、B;
彩色像素;
对于(int y=0;y
发件人:


如果您想了解有关问题和颜色矩阵的更多信息,请继续以下链接:

您没有设置
Matrix33
Matrix44
。我的理解是,
Matrix33
将是alpha组件,因此我怀疑您正在使整个图像透明

尝试设置
Matrix33=1

var gfxPicture = Graphics.FromImage(img); 
==>

DrawImage可能会扭曲图像,GetPixel速度较慢,请尝试WPF imaging API


我使用WPF和创建反转(负)效果。

使用颜色矩阵进行像素操作的快速替代方法:

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);
}
公共静态无效BitMapInvertColor(位图bitmapImage)
{
var bitmapRead=bitmapImage.LockBits(新矩形(0,0,bitmapImage.Width,bitmapImage.Height),ImageLockMode.ReadOnly,PixelFormat.Format32bppPArgb);
var bitmapLength=bitmapRead.Stride*bitmapRead.Height;
var bitmapBGRA=新字节[bitmapLength];
封送处理副本(bitmapRead.Scan0、bitmapBGRA、0、bitmapLength);
bitmapImage.UnlockBits(bitmapRead);
对于(int i=0;i
丹答案的VB版本。它就像一个符咒

 Public Function Transform(source As Bitmap) As Bitmap
    'create a blank bitmap the same size as original
    Dim newBitmap As New Bitmap(source.Width, source.Height)

    'get a graphics object from the new image
    Dim g As Graphics = Graphics.FromImage(newBitmap)

    ' create the negative color matrix
    Dim colorMatrix As New ColorMatrix(New Single()() {New Single() {-1, 0, 0, 0, 0}, New Single() {0, -1, 0, 0, 0}, New Single() {0, 0, -1, 0, 0}, New Single() {0, 0, 0, 1, 0}, New Single() {1, 1, 1, 0, 1}})

    ' create some image attributes
    Dim attributes As New ImageAttributes()

    attributes.SetColorMatrix(colorMatrix)

    g.DrawImage(source, New Rectangle(0, 0, source.Width, source.Height), 0, 0, source.Width, source.Height, _
        GraphicsUnit.Pixel, attributes)

    'dispose the Graphics object
    g.Dispose()

    Return newBitmap
End Function
我使用“SIMD支持的向量”使代码比指针更快。它位于System.Numerics命名空间下。但在使用这些类之前,您需要从NuGet获得System.Numerics的更新。只需搜索System.Numerics.Anyways这是我的类以反转图像

public class VBitmap : IDisposable
{        

    public short Width { get; private set; }
    public short Height { get; private set; }
    public int Stride { get; private set; }
    public int PixelLenght { get; private set; }
    public byte BytesperPixel { get; private set; }
    public PixelFormat PixelFormat { get; private set; }
    public byte[] Pixels { get; private set; }

    public VBitmap(string path)
    {
        using (Bitmap bmp = new Bitmap(path))
        {
            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
            Width = checked((short)bmp.Width);
            Height = checked((short)bmp.Height);
            Stride = bmpdata.Stride;
            PixelLenght = Stride * Height;
            BytesperPixel = checked((byte)(Stride / Width));
            PixelLenght = (PixelLenght % 16) != 0 ? PixelLenght + (PixelLenght % 16) : PixelLenght;
            PixelFormat = bmp.PixelFormat;
            Pixels = new byte[PixelLenght];

            Marshal.Copy(bmpdata.Scan0, Pixels, 0, PixelLenght);
            bmp.UnlockBits(bmpdata);
        }
    }
    ~VBitmap()
    {
        Dispose();
    }

    public void InvertPixels()
    {
        byte[] resultarray = Pixels;
        unsafe
        {
            fixed (byte* result_ptr = resultarray)
            {
                for (int i = 0; i < PixelLenght; i += 16)
                    (~new Vector<byte>(Pixels, i)).CopyTo(resultarray, i);
            }
        }
    }

    public void InvertPixels(string name)
    {
        byte[] resultarray = Pixels;
        unsafe
        {
            fixed (byte* result_ptr = resultarray)
            {
                for (int i = 0; i < PixelLenght; i += 16)
                    (~new Vector<byte>(Pixels, i)).CopyTo(resultarray, i);
                SaveImage(name);
            }
        }
    }

    public unsafe void SaveImage(string name)
    {
        fixed (byte* p_ptr = Pixels)
        {
            using (Bitmap resultbmp = new Bitmap(Width, Height, Stride, PixelFormat, (IntPtr)p_ptr))
            {
                resultbmp.Save(name, ImageFormat.Jpeg);
            }
        }
    }

    public void Dispose()
    {
        Width = 0;
        Height = 0;
        Stride = 0;
        PixelLenght = 0;
        BytesperPixel = 0;
        Pixels = null;
        GC.Collect();
    }
}

您还需要设置Matrix33=1和Matrix44=1,以保留这些项目的标识。如果图像为8bpp,您可以将其托盘反转。-1表示通过每个像素的超慢速迭代+1链接到鲍伯·鲍威尔。如前所述,这太慢了!不管怎样,谢谢这太慢了。细节:我改了,但没用。你能发布一个WPF代码片段吗?谢谢。为了清楚起见,我正在尝试创建一个应用程序的反转屏幕截图。我复制粘贴了它。它创建了相同的黑色图像!您是向下滚动到实际解决方案,还是只是复制第一个看起来像代码的东西?反转图形颜色怎么样?比如,在OnPaint事件中反转图像。太好了!谢谢你:D
 Public Function Transform(source As Bitmap) As Bitmap
    'create a blank bitmap the same size as original
    Dim newBitmap As New Bitmap(source.Width, source.Height)

    'get a graphics object from the new image
    Dim g As Graphics = Graphics.FromImage(newBitmap)

    ' create the negative color matrix
    Dim colorMatrix As New ColorMatrix(New Single()() {New Single() {-1, 0, 0, 0, 0}, New Single() {0, -1, 0, 0, 0}, New Single() {0, 0, -1, 0, 0}, New Single() {0, 0, 0, 1, 0}, New Single() {1, 1, 1, 0, 1}})

    ' create some image attributes
    Dim attributes As New ImageAttributes()

    attributes.SetColorMatrix(colorMatrix)

    g.DrawImage(source, New Rectangle(0, 0, source.Width, source.Height), 0, 0, source.Width, source.Height, _
        GraphicsUnit.Pixel, attributes)

    'dispose the Graphics object
    g.Dispose()

    Return newBitmap
End Function
public class VBitmap : IDisposable
{        

    public short Width { get; private set; }
    public short Height { get; private set; }
    public int Stride { get; private set; }
    public int PixelLenght { get; private set; }
    public byte BytesperPixel { get; private set; }
    public PixelFormat PixelFormat { get; private set; }
    public byte[] Pixels { get; private set; }

    public VBitmap(string path)
    {
        using (Bitmap bmp = new Bitmap(path))
        {
            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
            Width = checked((short)bmp.Width);
            Height = checked((short)bmp.Height);
            Stride = bmpdata.Stride;
            PixelLenght = Stride * Height;
            BytesperPixel = checked((byte)(Stride / Width));
            PixelLenght = (PixelLenght % 16) != 0 ? PixelLenght + (PixelLenght % 16) : PixelLenght;
            PixelFormat = bmp.PixelFormat;
            Pixels = new byte[PixelLenght];

            Marshal.Copy(bmpdata.Scan0, Pixels, 0, PixelLenght);
            bmp.UnlockBits(bmpdata);
        }
    }
    ~VBitmap()
    {
        Dispose();
    }

    public void InvertPixels()
    {
        byte[] resultarray = Pixels;
        unsafe
        {
            fixed (byte* result_ptr = resultarray)
            {
                for (int i = 0; i < PixelLenght; i += 16)
                    (~new Vector<byte>(Pixels, i)).CopyTo(resultarray, i);
            }
        }
    }

    public void InvertPixels(string name)
    {
        byte[] resultarray = Pixels;
        unsafe
        {
            fixed (byte* result_ptr = resultarray)
            {
                for (int i = 0; i < PixelLenght; i += 16)
                    (~new Vector<byte>(Pixels, i)).CopyTo(resultarray, i);
                SaveImage(name);
            }
        }
    }

    public unsafe void SaveImage(string name)
    {
        fixed (byte* p_ptr = Pixels)
        {
            using (Bitmap resultbmp = new Bitmap(Width, Height, Stride, PixelFormat, (IntPtr)p_ptr))
            {
                resultbmp.Save(name, ImageFormat.Jpeg);
            }
        }
    }

    public void Dispose()
    {
        Width = 0;
        Height = 0;
        Stride = 0;
        PixelLenght = 0;
        BytesperPixel = 0;
        Pixels = null;
        GC.Collect();
    }
}
static void Main(string[] args)
        {
            new VBitmap("testp.png").InvertPixels("qq.jpg");//Inverts the given bitmap and saves it.   
        }