【问题标题】:Storing images in buffer将图像存储在缓冲区中
【发布时间】:2018-02-04 13:51:05
【问题描述】:

我正在编写我的第一个图像编辑程序(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;
}

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

我的函数/过滤器非常基本,我不使用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,这绝对是问题的一部分。

【问题讨论】:

    标签: c# image winforms bitmap buffer


    【解决方案1】:

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

    首先,考虑一下您编写的所有 FileStream 内容的这种简单替代方案。

    Bitmap input = new Bitmap(pathToFile);
    

    另外,您的GetImage 函数实际上是LoadImageFromDisk 函数。所以要做的第一件事是确保你只做一次,并将输入的 Bitmap 对象保存在内存中并重用它。在输入图像上调用 LockBits 时,使用 ReadOnly 访问。

    如果您想进行修改(例如应用图像过滤器),则将此过滤器操作的结果存储在新的输出图像中,而不是覆盖内存中的原始图像。然后,如果您想更改过滤器的详细信息,您仍然可以保留原来的内容。

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

    当您在输出图像上使用 LockBits 时,请使用 WriteOnly 访问。

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

    最后,无论您的过滤器是什么,看看您是否可以使用 Parallel.For 一次对其进行操作并使用您的所有处理器。

    【讨论】:

    • 已经尝试实施您的一些建议并且到目前为止效果很好,非常感谢。访问数据的不安全上下文是什么意思?
    • unsafe 允许您从 BitmapData.Scan0 的 IntPtr 创建一个 byte* 指针并直接访问数据。你必须在你的项目设置中allow unsafe;默认禁用。
    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2012-01-27
    相关资源
    最近更新 更多