public unsafe Bitmap MedianFilter(Bitmap Img)
{
int Size =2;
List<byte> R = new List<byte>();
List<byte> G = new List<byte>();
List<byte> B = new List<byte>();
int ApetureMin = -(Size / 2);
int ApetureMax = (Size / 2);
BitmapData imageData = Img.LockBits(new Rectangle(0, 0, Img.Width, Img.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
byte* start = (byte*)imageData.Scan0.ToPointer ();
for (int x = 0; x < imageData.Width; x++)
{
for (int y = 0; y < imageData.Height; y++)
{
for (int x1 = ApetureMin; x1 < ApetureMax; x1++)
{
int valx = x + x1;
if (valx >= 0 && valx < imageData.Width)
{
for (int y1 = ApetureMin; y1 < ApetureMax; y1++)
{
int valy = y + y1;
if (valy >= 0 && valy < imageData.Height)
{
Color tempColor = Img.GetPixel(valx, valy);// error come from here
R.Add(tempColor.R);
G.Add(tempColor.G);
B.Add(tempColor.B);
}
}
}
}
}
}
R.Sort();
G.Sort();
B.Sort();
Img.UnlockBits(imageData);
return Img;
}
我试着这样做。但我得到一个错误调用“位图区域已被锁定”任何人都可以帮助如何解决这个问题。 (错误位置突出显示)
答案 0 :(得分:5)
GetPixel
是访问图像的懒散方式,如果其他人开始直接弄乱图像缓冲区,则不再工作(正如您所注意到的)。你为什么要那样做?
检查http://www.bobpowell.net/lockingbits.htm,了解对快速图像处理的一些了解。
在这种情况下,请改用以下内容:
int pixelSize = 4 /* Check below or the site I linked to and make sure this is correct */
byte* color =(byte *)imageData .Scan0+(y*imageData .Stride) + x * pixelSize;
请注意,这会为您提供该像素的第一个字节。根据您正在查看的颜色格式(ARGB?RGB?..),您还需要访问以下字节。似乎无论如何都要套用你的用例,因为你只关心字节值,而不是Color
值。
所以,在有了一些闲暇时间之后,这就是我想出来的(请花时间去理解并检查它,我确保它已编译完毕):
public void SomeStuff(Bitmap image)
{
var imageWidth = image.Width;
var imageHeight = image.Height;
var imageData = image.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
var imageByteCount = imageData.Stride*imageData.Height;
var imageBuffer = new byte[imageByteCount];
Marshal.Copy(imageData.Scan0, imageBuffer, 0, imageByteCount);
for (int x = 0; x < imageWidth; x++)
{
for (int y = 0; y < imageHeight; y++)
{
var pixelColor = GetPixel(imageBuffer, imageData.Stride, x, y);
// Do your stuff
}
}
}
private static Color GetPixel(byte[] imageBuffer, int imageStride, int x, int y)
{
int pixelBase = y*imageStride + x*3;
byte blue = imageBuffer[pixelBase];
byte green = imageBuffer[pixelBase + 1];
byte red = imageBuffer[pixelBase + 2];
return Color.FromArgb(red, green, blue);
}
此
PixelFormat
(关于每像素的像素大小/字节数和值的顺序)。如果您更改PixelFormat
,则会中断。