在缓冲区中存储图像

Storing images in buffer

我正在编写我的第一个图像编辑程序(c#、winforms),但我对缓冲区和高效存储数据非常不满意。 我有一个包含图片的文件夹,并通过 FolderBrowserDialog:

将文件加载到 string[]
files = Directory.GetFiles(fbd.SelectedPath);

我总是在图片框中显示其中一张图片。我有各种适用的功能,例如显示图像上的过滤器。我所有的函数都在位图上工作,我所有的函数基本上都是通过调用另一个函数开始的:

Bitmap bmp = GetImage();

和:

Image GetImage()
{
    FileStream imageStream = new FileStream(Convert.ToString(files[SelIndex]), FileMode.Open);
    Image image = Image.FromStream(imageStream);
    imageStream.Close();
    return image;
}

每当我调用我的一个函数时(例如因为我想显示不同的图像并查看过滤器如何应用),在显示新图片之前我会遇到痛苦的滞后。就我而言,每次我调用我的一个函数时,它都会深入到图片所在的原始文件夹并从那里获取数据,我相信这就是延迟的原因。 首先:对吗?其次:有什么方法可以避免这种情况? 我可以想象将数据保存在某种缓冲区中吗?

我的 functions/filters 非常基础,我不使用 SetPixel 方法但是:

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

byte[] bytes = new byte[data.Height * data.Stride];

Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

//whatever my filter is

Marshal.Copy(bytes, 0, data.Scan0, bytes.Length);

bmp.UnlockBits(data);

因为速度更快,所以延迟不应该来自于此。

编辑: 另外,我正在处理 .tif 文件,每个大约 12 MB,这绝对是问题的一部分。

你说得对,文件操作很昂贵。它们涉及两个相对较慢的操作:从磁盘读取数据和解压缩数据。

首先,考虑用这个简单的替代方法来替代您编写的所有 FileStream 内容。

Bitmap input = new Bitmap(pathToFile);

此外,您的 GetImage 函数实际上是一个 LoadImageFromDisk 函数。所以首先要做的是确保只执行一次并将输入的 Bitmap 对象保存在内存中并重新使用它。在输入图像上调用 LockBits 时,使用 ReadOnly 访问。

如果您想进行修改(如应用图像滤镜),则将此滤镜操作的结果存储在新的 output 图像中,而不是覆盖原始图像记忆。然后如果你想改变过滤器的细节,你仍然有原来的东西。

Bitmap output = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppRgb);

当您对输出图像进行 LockBit 时,请使用 WriteOnly 访问权限。

此外,考虑使用 不安全的 上下文直接访问数据而不是使用 Marshal.Copy,它会为您节省一个缓冲区副本。

最后,无论您的过滤器是什么,看看您是否可以利用 Parallel.For 一次在其上运行并利用所有处理器。