c# - system.drawing.image 中的“System.OutOfMemoryException”
问题描述
我以字节数组的形式存储我的网站图像,但是当我尝试将它们保存为 jpeg 文件时,这个文件中的一些会抛出异常。这是我获取图像的代码:
IList<PropertyInfo> properties = typeof(ApplicationUser).GetProperties()
.Where(x => x.PropertyType == typeof(Byte[])).ToList();
var imaBytes = property.GetValue(user, null) as Byte[];
if (imaBytes == null || imaBytes.Length == 0) continue;
Image userImage = ImageHelper.byteArrayToImage(imaBytes);
userImage.Save(pathname + $@"\{DirName}\" + property.Name + ".jpg", ImageFormat.Jpeg);
这是我的ImageHelper.byteArrayToImage
:
public static Image byteArrayToImage(byte[] byteArrayIn)
{
try
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
using (var image = Image.FromStream(ms,false,true))
{
byteArrayIn = new byte[0];
return new Bitmap(image);
}
}
catch (Exception e)
{
Logger.log(e);
}
}
编辑:
我使用语句包装 MemoryStream 和 Image 代码并更改我的代码并添加 ImageToDisk 方法:
public static void ImageToDisk(byte[] byteArrayIn, string pathToSave)
{
try
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
using (var image = Image.FromStream(ms, false, true))
{
image.Save(pathToSave, ImageFormat.Jpeg);
image.Dispose();
}
}
}
catch (Exception e)
{
Logger.log(e);
throw;
}
}
主要代码是这样的:
foreach (var property in properties)
{
try
{
var imaBytes = property.GetValue(user, null) as Byte[];
if (imaBytes == null || imaBytes.Length == 0)
{
continue;
}
ImageHelper.ImageToDisk(imaBytes, pathname + $@"\{DirName}\" + property.Name + ".jpg");
}
catch (Exception ex)
{
LogException(ex);
}
}
但现在我得到了system.runtime.interopservices.externalexception
编辑 2:
我完全头晕目眩!!!似乎有些用户从 IE 上传图像,并且 IE 将 MIME 类型更改为图像/PJPEG
错误是一些具有此 MIME 类型的文件,但也有一些其他文件正确保存,没有任何异常
我该如何解决这个错误?
image/PJPEG
解决方案
这个文件的一些抛出异常
我几乎可以肯定问题在于处理您的图像。确保所有资源都已释放:
using (Image userImage = ImageHelper.byteArrayToImage(imaBytes))
{
//do whatever you need
userImage.Save(pathname + $@"\{DirName}\" + property.Name + ".jpg", ImageFormat.Jpeg);
}
位图消耗大量内存。引擎盖下Image
使用GdipLoadImageFromStream
方法。要释放资源,它应该与GdipDisposeImage
. 这就是Image.Dispose()
方法内部发生的事情。
推荐阅读
- reactjs - 当状态包含来自api调用的响应时如何在reactjs中使用三元运算
- android - 选中复选框时,它会更新 recyclerview 中的其他行。用于更新和绑定数据的 DiffUtils 和 DataBinding
- python - 使用 bad_alloc 调试 Python/C++ 程序
- oracle - 从 Oracle RDS SE 中查询 RDS 端点名称
- r - 如何连接两个文件并替换变量中的错误值?
- reactjs - 为什么按钮的输出会出现这样的问题?
- python - 如何在 on_message() 中执行静音命令
- c++ - 如何将函数重载集作为模板参数传递
- reactjs - 目前无法安装此应用程序。无法硬链接副本。(第二次运行)
- twilio - 检查 twilio 客户端是否正忙于通话或可用