- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我的程序中,我正在创建一些大图片(Image
对象),并将它们保存到磁盘。然后我将它们添加到列表 List<Image>
但在保存 50 张图片并将它们添加为 Image
之后反对我的imageList
它占用了大量内存。我尝试在 50 张图像上执行此操作并仅保存纯图像对象,我的程序在进程管理器中增加到 160 MB。所以我必须找到一种方法来保存图片并将它们添加到列表中,而不会让程序占用所有内存。
所以我有几个解决方案,我很想听听您对它们的看法,或者您是否有更好的解决方案。
byte[]
图像对象的数组。byte[]
图像对象的数组到字符串,然后压缩字符串。我在 C# 中执行此操作。
最佳答案
不要使用 .Net DeflateStream 等压缩图像(因为存在一个已知问题,在所有情况下它实际上都会增加数据的大小)- 将其直接保存为 .png 之类的文件。
Bitmap bmp;
// ...
bmp.Save("foo.png", System.Drawing.Imaging.ImageFormat.Png);
确保处置您创建的图像(在保存它们之后)。
您不能压缩内存中的图像 - 因为 Windows GDI(.Net 使用)要求图像本质上是未压缩的位图形式(因此当您加载压缩图像时,它会被解压缩)。
您应该考虑按需加载它们。这是一个类似于 ImageList
的类,您可能会发现它很有用:
public class DelayedImagedList : Component
{
// Item1 = Dispose for the image.
// Item2 = At creation: the method to load the image. After loading: the method to return the image.
// Item3 = The original filename.
private List<Tuple<Action, Func<Image>, string>> _images = new List<Tuple<Action,Func<Image>,string>>();
private Dictionary<string, int> _imageKeyMap = new Dictionary<string, int>();
// Access images.
public Image this[string key] { get { return _images[_imageKeyMap[key]].Item2(); } }
public Image this[int index] { get { return _images[index].Item2(); } }
public int Count { get { return _images.Count; } }
// Use this to add an image according to its filename.
public void AddImage(string key, string filename) { _imageKeyMap.Add(key, AddImage(filename)); }
public int AddImage(string filename)
{
var index = _images.Count;
_images.Add(Tuple.Create<Action, Func<Image>, string>(
() => {}, // Dispose
() => // Load image.
{
var result = Image.FromFile(filename);
// Replace the method to load the image with one to simply return it.
_images[index] = Tuple.Create<Action, Func<Image>, string>(
result.Dispose, // We need to dispose it now.
() => result, // Just return the image.
filename);
return result;
},
filename));
return index;
}
// This will unload an image from memory.
public void Reset(string key) { Reset(_imageKeyMap[key]); }
public void Reset(int index)
{
_images[index].Item1(); // Dispose the old value.
var filename = _images[index].Item3;
_images[index] = Tuple.Create<Action, Func<Image>, string>(
() => { },
() =>
{
var result = Image.FromFile(filename);
_images[index] = Tuple.Create<Action, Func<Image>, string>(
result.Dispose,
() => result,
filename);
return result;
},
filename);
}
// These methods are available on ImageList.
public void Draw(Graphics g, Point pt, int index) { g.DrawImage(this[index], pt); }
public void Draw(Graphics g, int x, int y, int index) { g.DrawImage(this[index], x, y); }
public void Draw(Graphics g, int x, int y, int width, int height, int index) { g.DrawImage(this[index], x, y, width, height); }
protected override void Dispose(bool disposing)
{
if (disposing)
{
foreach (var val in _images) { val.Item1(); }
_images.Clear();
_imageKeyMap.Clear();
}
base.Dispose(disposing);
}
}
关于c# - 保存图像文件和节省内存的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7114198/
我试图找出在将数据传输到设备之前将数据复制到固定内存是否有意义,因为我对输入数据的分配没有影响(它是一个库)。 std::vector idata(WORK_SIZE); int *idata_ali
model.save() 让我很困惑。 示例。我将我的 mongoose.model(mongoose.schema) 移动到单独的 model.js 文件中。当我使用这种方法创建模型时,以下问题困扰
我正在用 Java Swing 制作模拟时钟。要计算我需要的时钟指针角度: 我可以通过 System.currentTimeMillis() 获得的以毫秒为单位的 UTC 时间 时区偏移 TimeZo
编辑 我的应用程序中有声音,该声音在应用程序启动时开始播放。此外,我还有两种播放和停止声音的方法: -(void)playBgMusic { NSString *path = [[NSBundle m
所以我的应用有 1 个 Activity 和 4 个 fragment ,其中一个有 Chronometer 来显示经过了多少时间。 它工作正常,但我有一个问题,每次我移动到另一个 fragment
我是 FireDAC 新手,遇到问题。我想在Delphi XE7中使用FireDAC读写SQLite数据库。我尝试的大部分方法都有效,但我在将 TTime 保存到 SQLite DB 时遇到问题。 这
这是我使用基本 Node.js 服务器创建的示例站点。我能够成功发布、创建给定架构的用户,然后“保存”到数据库;但是,保存不会返回用户对象,并且在我的实际数据库中找不到。连接也返回成功。 main.j
我有一台配备 2 Gb Nvidia GPU 的 Mac Book Pro。我正在尝试利用我所有的 GPU 内存进行计算(python 代码)。如果我绕过 GUI 界面并仅通过命令行访问我的机器,我可
我希望使用 Powerpoint 创建一种测验,我想保存用户提供的输入。 例如:如果我问这个问题:你最喜欢什么颜色?当他们回答问题并单击下一步按钮时,我想保存文本框的值并将其附加到输出文件中。 我已经
我是一名优秀的程序员,十分优秀!