我正在尝试使用LockBits从设置图像中获取所有像素,并通过for
遍历每个像素。但我得到的像素不正确。我在一秒钟内兴奋不已。
代码:
Bitmap bmp = new Bitmap(ImagePath);
pictureBox1.Image = bmp;
Rectangle bmpRec = new Rectangle(0, 0,
bmp.Width, bmp.Height); // Creates Rectangle for holding picture
BitmapData bmpData = bmp.LockBits(bmpRec,
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb); // Gets the Bitmap data
IntPtr Pointer = bmpData.Scan0; // Set pointer
int DataBytes = Math.Abs(bmpData.Stride) * bmp.Height; // Gets array size
byte[] rgbValues = new byte[DataBytes]; // Creates array
Marshal.Copy(Pointer, rgbValues, 0, DataBytes); // Copies of out memory
StringBuilder Pix = new StringBuilder(" ");
// pictureBox1.Image = bmp;
StringBuilder EachPixel = new StringBuilder("");
for (int i = 0; i < bmpData.Width; i++)
{
for (int j = 0; j < bmpData.Height; j++)
{
var pixel = rgbValues[i + j * Math.Abs(bmpData.Stride)];
Pix.Append(" ");
Pix.Append(Color.FromArgb(pixel));
}
}
现在我创建了一个纯蓝色的2x2像素图像。我的输出应该是
255 0 0 255 255 0 0 255 255 0 0 255 255 0 0 255 (A R G B)
但我有点像
颜色[A = 0,R = 0,G = 0,B = 255]颜色[A = 0,R = 0,G = 0,B = 255]颜色[A = 0,R = 0,G = 0,B = 0]颜色[A = 0,R = 0,G = 0,B = 0]
我哪里错了?对不起,如果我无法解释究竟是什么错误。基本上像素输出不正确,与输入bmp不匹配。
答案 0 :(得分:0)
我不确定你到底想要做什么......我想你误解了Scan0和Stride是如何工作的。 Scan0是指向内存中图像开头的指针。 Stride是内存中每行的长度,以字节为单位。你已经用bmp.LockBits将图像锁定在内存中,你不需要使用它来制作它。
Bitmap bmp = new Bitmap(ImagePath);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
StringBuilder sb = new StringBuilder();
unsafe
{
for (int y = 0; y < bmp.Height; y++)
{
byte* row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);
for (int x = 0; x < bmp.Width; x++)
{
byte B = row[(x * 4)];
byte G = row[(x * 4) + 1];
byte R = row[(x * 4) + 2];
byte A = row[(x * 4) + 3];
sb.Append(String.Format("{0} {1} {2} {3} ", A, R, G, B);
}
}
}
答案 1 :(得分:0)
通过更改输出内容和方式来解决问题。
我现在使用Color ARGB = Color.FromArgb(A, R, G, B)
我现在也使用像素数组。
byte B = row[(x * 4)];
byte G = row[(x * 4) + 1];
byte R = row[(x * 4) + 2];
byte A = row[(x * 4) + 3];