我想反转一个Image对象。目前我的代码如下所示:
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;
}
然而,当我运行它并在PictureBox
中显示时,结果是黑色图像。我在Windows 8 Release预览版的Visual Studio 2012中运行它。如果有更好的方法,请告诉我。感谢。
答案 0 :(得分:8)
试试这个:http://mariusbancila.ro/blog/2009/11/13/using-colormatrix-for-creating-negative-image/
public Bitmap Transform(Bitmap source)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(source.Width, source.Height);
//get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
// create the negative color matrix
ColorMatrix colorMatrix = new ColorMatrix(new float[][]
{
new float[] {-1, 0, 0, 0, 0},
new float[] {0, -1, 0, 0, 0},
new float[] {0, 0, -1, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {1, 1, 1, 0, 1}
});
// create some image attributes
ImageAttributes attributes = 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;
}
答案 1 :(得分:3)
使用ColorMatrix进行像素操作的快速替代方法:
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);
}
答案 2 :(得分:0)
通过倒置你的意思是创造一个负面的?如果是,这里是一个片段:
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));
}
}
}
来自:http://www.smokycogs.com/blog/image-processing-in-c-sharp-inverting-an-image/
如果您想了解有关问题和颜色矩阵的更多信息,请继续以下链接:http://www.bobpowell.net/negativeimage.htm
答案 3 :(得分:0)
您没有设置Matrix33
或Matrix44
。我的理解是Matrix33
将是alpha组件,因此我怀疑你是在使整个图像透明。
尝试设置Matrix33 = 1
。
答案 4 :(得分:0)
我使用WPF和this library来创建反转(负面)效果。
答案 5 :(得分:0)
丹的答案的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
答案 6 :(得分:0)
我使用“SIMD支持的向量”使代码比指针更快。它在System.Numerics namespace.But下使用这些类之前,你需要从NuGet获取System.Numerics的更新。只需搜索System.Numerics。无论如何,我的班级反转图像
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();
}
}
Usage.Note:要从向量中获得最佳性能,您需要在发布模式下运行代码:
static void Main(string[] args)
{
new VBitmap("testp.png").InvertPixels("qq.jpg");//Inverts the given bitmap and saves it.
}
答案 7 :(得分:-1)
var gfxPicture = Graphics.FromImage(img);
==&GT;
var gfxPicture = Graphics.FromImage(bmpPicture);
DrawImage可能会扭曲图像,GetPixel很慢,请尝试WPF成像API