Graphics g;
using (var bmp = new Bitmap(_frame, _height, PixelFormat.Format24bppRgb))
{
var data = bmp.LockBits(new Rectangle(0, 0, _frame, _height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
var bmpWidth = data.Stride;
var bytes = bmpWidth * _height;
var rgb = new byte[bytes];
var ptr = data.Scan0;
Marshal.Copy(ptr, rgb, 0, bytes);
for (var i = 0; i < _frame; i++)
{
var i3 = (i << 1) + i;
for (var j = 0; j < _height; j++)
{
var ij = j * bmpWidth + i3;
var val = (byte)(_values[i, j]);
rgb[ij] = val;
rgb[ij + 1] = val;
rgb[ij + 2] = val;
}
}
Marshal.Copy(rgb, 0, ptr, bytes);
bmp.UnlockBits(data);
g = _box.CreateGraphics();
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(bmp, 0, 0, _box.Width, _box.Height);
}
g.Dispose();我使用这段代码在PictureBox中转换RGB值数组(灰度),但速度很慢。请告诉我我的错误。目前,一个441,000个项目的数组处理了35毫秒。我需要在同一时间内处理400万的数组。
发布于 2011-09-24 07:42:16
您可以跳过将数据从映像复制到数组的第一个Array.Copy,因为无论如何您都将覆盖数组中的所有数据。
这将减少大约25%的时间,但如果你想更快,你将不得不使用不安全的代码块,以便您可以使用指针。这样,您可以在访问数组时绕过范围检查,并且可以直接将数据写入图像数据,而不是复制它。
发布于 2011-09-25 05:10:37
我完全同意Guffa的回答。使用不安全的代码块会加快速度。要进一步提高性能,可以使用.Net框架中的Parallel类并行执行for循环。对于较大的位图,这会提高性能。下面是一个小的代码示例:
using (Bitmap bmp = (Bitmap)Image.FromFile(@"mybitmap.bmp"))
{
int width = bmp.Width;
int height = bmp.Height;
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height),
System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
byte* s0 = (byte*)bd.Scan0.ToPointer();
int stride = bd.Stride;
Parallel.For(0, height, (y1) =>
{
int posY = y1*stride;
byte* cpp = s0 + posY;
for (int x = 0; x < width; x++)
{
// Set your pixel values here.
cpp[0] = 255;
cpp[1] = 255;
cpp[2] = 255;
cpp += 3;
}
});
bmp.UnlockBits(bd);
}为了保持示例简单,我将像素值设置为常量值。注意,要编译上面的例子,你必须允许不安全的代码。
霍普,这有帮助。
发布于 2011-09-24 07:55:54
除了Guffa的优秀建议之外,我还建议您分析一下您的代码,看看它花费了哪些时间。请确保在对此进行计时时,在未附加调试器的情况下以发布模式运行。
如果对DrawImage的调用占用了大部分时间,我也不会感到惊讶。您在那里缩放图像,这可能是相当昂贵的。您要将图像绘制到的框有多大?
最后,尽管这不会影响性能,但您应该将代码更改为:
using (Graphics g = _box.CreateGraphics())
{
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(bmp, 0, 0, _box.Width, _box.Height);
}并去掉示例中的第一行和最后一行。
https://stackoverflow.com/questions/7535812
复制相似问题