我在List pointtocolor上进行循环,包含超过50000像素的坐标,然后我试图在Bitmap bmpBackClouds上为它们着色。
我第一次尝试使用该行:
if ((int)p + (int)(x + y) < bD.Stride * bD.Height)
然而它从未介入,从未做过p[1] = p[2] = (byte)255;
行。
所以现在我没有使用这个IF而且它正在做所有的线路。
但最终我得到了与原始相同的Bitmap,因为它没有任何颜色。
float x, y;
bD = bmpBackClouds.LockBits(
new System.Drawing.Rectangle(0, 0, bmpBackClouds.Width, bmpBackClouds.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
IntPtr s0 = bD.Scan0;
unsafe
{
byte* p;
byte* pBU = (byte*)(void*)s0;
for (int i = 0; i < pointtocolor.Count; i++)
{
p = (byte*)(void*)s0;
x = pointtocolor[i].X * (float)currentFactor;
y = pointtocolor[i].Y * (float)currentFactor;
if ((int)x >= bmpBackClouds.Width || (int)y >= bmpBackClouds.Height)
{
continue;
}
x = (int)(y * (float)bD.Stride);
y = (int)(x * 4F);
p += (int)(x + y);
if ((int)p + (int)(x + y) < bD.Stride * bD.Height)
{
if (x + y > 3)
p -= (p - pBU) % 4;
p[1] = p[2] = (byte)255;
p[0] = (byte)0;
p[3] = (byte)255;
}
}
}
bmpBackClouds.UnlockBits(bD);
这是不安全的代码部分:
不安全 { byte * p; byte * pBU =(byte *)(void *)s0;
for (int i = 0; i < pointtocolor.Count; i++)
{
//set pointer to the beggining
p = (byte*)(void*)s0;
x = pointtocolor[i].X * (float)currentFactor;
y = pointtocolor[i].Y * (float)currentFactor;
//check if point is inside bmp
if ((int)x >= bmpBackClouds.Width || (int)y >= bmpBackClouds.Height)
{
continue;
}
//Add offset where the point is. The formula: position = Y * stride + X * 4
x = (int)(y * (float)bD.Stride);
y = (int)(x * 4F);
p += (int)(x + y);
//here check, whether the pointer's at a correct position
if (x + y > 3)
p -= (p - pBU) % 4;
//set yellow color
p[1] = p[2] = (byte)255;
p[0] = (byte)0;
p[3] = (byte)255;
}
}
汉斯的解决方案正在运作我只是有一个小的例子,我在硬盘上的图像被涂上了正确的形状,但是相反或反转不确定如何调用它应该是什么:
在左边的屏幕截图中,我在har盘上找到了我用LockBits写的位图。 在右侧,它是我的程序和一个用红色绘制的矩形,这个矩形应该是位图上的彩色区域。但是在Bitmap上,我看到这个矩形但看起来却相反或相反。
问题是LockBits代码是否有问题?或者它看起来更像我的其他代码?
答案 0 :(得分:0)
(p - pBU)%4 始终为零。差异总是4的倍数,因为每个像素有4字节的信息。 p指针从pBU指向的开头到4的倍数。如果要测试点是否在矩形中,请执行以下操作:
GraphicsPath gp = new GraphicsPath();
gp.AddRectangle(new RectangleF(?, ?, ?, ?)); //fill the values of your rectangle
for (int i = 0; i < pointtocolor.Count; i++)
{
if(gp.IsVisible (pointtocolor[i].X * (float)currentFactor, pointtocolor[i].Y * (float)currentFactor)
{
//is inside
}
}
修改
扫描位图并使用 bD.Stride 使用 int 指针查看宽度时出错是因为stride给出了颜色字节数 像素数
int *p;
p = (int*)(void*)s0;
//x, y the position coordinates
p += y * bD.Stride + x * 4; //wrong
byte *p;
p = (byte*)(void*)s0;
//x, y the position coordinates
p += y * bD.Stride + x * 4; //correct
错误在这里
x = (int)(y * (float)bD.Stride);
y = (int)(x * 4F);
您正在使用之前的x来设置y!
正确的代码是:
float fx, fy;
int x, y;
bD = bmpBackClouds.LockBits(
new System.Drawing.Rectangle(0, 0, bmpBackClouds.Width, bmpBackClouds.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
IntPtr s0 = bD.Scan0;
unsafe
{
byte* p;
//byte* pBU = (byte*)(void*)s0;
for (int i = 0; i < pointtocolor.Count; i++)
{
p = (byte*)(void*)s0;
fx = pointtocolor[i].X * (float)currentFactor;
fy = pointtocolor[i].Y * (float)currentFactor;
if ((int)fx >= bmpBackClouds.Width || (int)fy >= bmpBackClouds.Height)
{
continue;
}
x = (int)fy * bD.Stride;
y = (int)fx * 4;
p += (x + y);
p[1] = p[2] = (byte)255;
p[0] = (byte)0;
p[3] = (byte)255;
}
}
bmpBackClouds.UnlockBits(bD);
瓦尔特