在 C# 中使用流加载位图的子矩形
Loading a subrectangle of a bitmap using streams in C#
我有位图作为 bmp 文件(没有压缩只是一个简单的位图)。我想从文件的子部分(矩形)创建内存流而不将整个文件加载到内存中。
目前,我读取整个位图只是为了稍后使用代表相对于图像大小的点的矩形进行裁剪。
using (FileStream fs = new FileStream(ImagePath, FileMode.Open))
{
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
Image temp = Image.FromStream(ms, false, false);
}
由于位图只是一个以颜色向量作为值的大矩阵,我不能创建一个自定义流来读取,只能在相关行和列之间读取以提高 运行 时间和内存使用率吗?处理后的图像永远不会离开内存或保存在任何地方。
编辑:还有没有办法在根本不使用文件流的情况下将文件直接加载到内存流?
听起来您想创建一个自定义 FileStream,它基本上忽略子矩形之外的任何区域的像素数据(我想是通过返回零?),从而减少 I/O 的总量。是的,这是可能的,但它就像编写自己的图像加载器一样棘手。您的流需要了解所有相关的位图 header 信息(适用时的压缩、位深度、行顺序、填充)以确定子矩形的正确内存偏移量。
我不相信它会为您节省很多 I/O 除非子矩形与原始图像相比 非常 小。即使您请求更少,硬盘驱动器也可能会以大约 4k 字节的块读取数据,因此对于 screen-sized 图像,最大的性能影响将是总行数。
如果我要走这条路(即只加载一个子矩形),我不会用自定义流来做。相反,我将从位图文件 headers 加载相关元数据,然后为子矩形创建具有正确大小和像素格式的 GDI+ 位图 object。然后就可以锁定位图,将像素数据直接读入位图object的内存中。
这不是微不足道的,所以除非你真的需要,否则不要这样做。
我有位图作为 bmp 文件(没有压缩只是一个简单的位图)。我想从文件的子部分(矩形)创建内存流而不将整个文件加载到内存中。
目前,我读取整个位图只是为了稍后使用代表相对于图像大小的点的矩形进行裁剪。
using (FileStream fs = new FileStream(ImagePath, FileMode.Open))
{
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
Image temp = Image.FromStream(ms, false, false);
}
由于位图只是一个以颜色向量作为值的大矩阵,我不能创建一个自定义流来读取,只能在相关行和列之间读取以提高 运行 时间和内存使用率吗?处理后的图像永远不会离开内存或保存在任何地方。
编辑:还有没有办法在根本不使用文件流的情况下将文件直接加载到内存流?
听起来您想创建一个自定义 FileStream,它基本上忽略子矩形之外的任何区域的像素数据(我想是通过返回零?),从而减少 I/O 的总量。是的,这是可能的,但它就像编写自己的图像加载器一样棘手。您的流需要了解所有相关的位图 header 信息(适用时的压缩、位深度、行顺序、填充)以确定子矩形的正确内存偏移量。
我不相信它会为您节省很多 I/O 除非子矩形与原始图像相比 非常 小。即使您请求更少,硬盘驱动器也可能会以大约 4k 字节的块读取数据,因此对于 screen-sized 图像,最大的性能影响将是总行数。
如果我要走这条路(即只加载一个子矩形),我不会用自定义流来做。相反,我将从位图文件 headers 加载相关元数据,然后为子矩形创建具有正确大小和像素格式的 GDI+ 位图 object。然后就可以锁定位图,将像素数据直接读入位图object的内存中。
这不是微不足道的,所以除非你真的需要,否则不要这样做。