gpt4 book ai didi

C# 如何将我的 getPixel/SetPixel 颜色处理转换为 Lockbits?

转载 作者:行者123 更新时间:2023-11-30 19:38:53 25 4
gpt4 key购买 nike

编辑:非常感谢您的回复。我在这里最需要的是示例代码,用于说明我对嵌套循环中的几行代码所做的工作,因为这在 GetPixel/SetPixel 中是有效的,但也是我无法使用 Lockbits 正确工作的。谢谢

我正在尝试将我的图像处理过滤器从 GetPixel/SetPixel 转换为 Lockbits,以缩短处理时间。 我也在 Stack Overflow、MSDN 和其他网站上看到了 Lockbits 教程,但我做错了。我从一个非常简单的过滤器开始,它只是减少绿色以创建一个红色和紫色效果。这是我的代码:

   private void redsAndPurplesToolStripMenuItem_Click(object sender, EventArgs e)
{
// Get bitmap from picturebox
Bitmap bmpMain = (Bitmap)pictureBoxMain.Image.Clone();

// search through each pixel via x, y coordinates, examine and make changes. Dont let values exceed 255 or fall under 0.
for (int y = 0; y < bmpMain.Height; y++)
for (int x = 0; x < bmpMain.Width; x++)
{
bmpMain.GetPixel(x, y);
Color c = bmpMain.GetPixel(x, y);
int myRed = c.R, myGreen = c.G, myBlue = c.B;
myGreen -= 128;
if (myGreen < 0) myGreen = 0;
bmpMain.SetPixel(x, y, Color.FromArgb(255, myRed, myGreen, myBlue));
}

// assign the new bitmap to the picturebox
pictureBoxMain.Image = (Bitmap)bmpMain;

// Save a copy to the HD for undo / redo.
string myString = Environment.GetEnvironmentVariable("temp", EnvironmentVariableTarget.Machine);
pictureBoxMain.Image.Save(myString + "\\ColorAppRedo.png", System.Drawing.Imaging.ImageFormat.Png);
}

因此 GetPixel/SetPixel 代码可以正常工作,但速度很慢。所以我试了一下:

    private void redsAndPurplesToolStripMenuItem_Click(object sender, EventArgs e)
{
// Get bitmap from picturebox
Bitmap bmpMain = (Bitmap)pictureBoxMain.Image.Clone();

Rectangle rect = new Rectangle(Point.Empty, bmpMain.Size);
BitmapData bmpData = bmpMain.LockBits(rect, ImageLockMode.ReadOnly, bmpMain.PixelFormat);

// search through each pixel via x, y coordinates, examine and make changes. Dont let values exceed 255 or fall under 0.
for (int y = 0; y < bmpMain.Height; y++)
for (int x = 0; x < bmpMain.Width; x++)
{
bmpMain.GetPixel(x, y);
Color c = new Color();
int myRed = c.R, myGreen = c.G, myBlue = c.B;
myGreen -= 128;
if (myGreen < 0) myGreen = 0;
bmpMain.SetPixel(x, y, Color.FromArgb(255, myRed, myGreen, myBlue));

}

bmpMain.UnlockBits(bmpData);

// assign the new bitmap to the picturebox
pictureBoxMain.Image = (Bitmap)bmpMain;

// Save a copy to the HD for undo / redo.
string myString = Environment.GetEnvironmentVariable("temp", EnvironmentVariableTarget.Machine);
pictureBoxMain.Image.Save(myString + "\\ColorAppRedo.png", System.Drawing.Imaging.ImageFormat.Png);
}

当它到达嵌套的第一行时抛出错误“System.Drawing.dll 附加信息中发生类型为‘System.InvalidOperationException’的未处理异常:位图区域已被锁定”环形。

我意识到这一定是初学者的错误,如果有人可以演示将这个非常简单的过滤器转换为 Lockbits 的正确方法,我将不胜感激。非常感谢

最佳答案

scan0 返回的数组是这种格式 BGRA BGRA BGRA BGRA ...等等,其中 B = 蓝色,G = 绿色,R = 红色,A = Alpha。

4 像素宽和 3 像素高的非常小的位图示例。

BGRA BGRA BGRA BGRA
BGRA BGRA BGRA BGRA
BGRA BGRA BGRA BGRA

stride = width*bytesPerPixel = 4*4 = 16 bytes
height = 3
maxLenght = stride*height= 16*3 = 48 bytes

要达到图像中的某个像素 (x, y) 使用此公式

int certainPixel = bytesPerPixel*x + stride * y;
B = scan0[certainPixel + 0];
G = scan0[certainPixel + 1];
R = scan0[certainPixel + 2];
A = scan0[certainPixel + 3];

    public unsafe void Test(Bitmap bmp)
{
int width = bmp.Width;
int height = bmp.Height;
//TODO determine bytes per pixel
int bytesPerPixel = 4; // we assume that image is Format32bppArgb
int maxPointerLenght = width * height * bytesPerPixel;
int stride = width * bytesPerPixel;
byte R, G, B, A;

BitmapData bData = bmp.LockBits(
new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite, bmp.PixelFormat);


byte* scan0 = (byte*)bData.Scan0.ToPointer();

for (int i = 0; i < maxPointerLenght; i += 4)
{
B = scan0[i + 0];
G = scan0[i + 1];
R = scan0[i + 2];
A = scan0[i + 3];

// do anything with the colors
// Set the green component to 0
G = 0;
// do something with red
R = R < 54 ? (byte)(R + 127) : R;
R = R > 255 ? 255 : R;
}


bmp.UnlockBits(bData);
}

你可以测试的是你自己。在画图或任何其他程序中创建一个非常小的位图(几个像素的宽度/高度),并在该方法的开头放置一个断点。

关于C# 如何将我的 getPixel/SetPixel 颜色处理转换为 Lockbits?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30542505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com