c# - 将 .bmp 作为 .png 保存到 MemoryStream 时出现 ExternalException
问题描述
我正在将一批 .bmp 转换为 .png。这是代码的相关部分:
foreach (string path in files) {
using (fs = new FileStream(path, FileMode.Open)) bmp = new Bitmap(fs);
using (ms = new MemoryStream()) {
bmp.Save(ms, ImageFormat.Png);
bmp.Dispose();
png = Image.FromStream(ms);
}
png.Save(path);
}
在该行bmp.Save(ms, ImageFormat.Png);
引发以下异常:
System.Runtime.InteropServices.ExternalException:“GDI+ 中发生一般错误。”
根据MSDN的说法,这意味着图像要么以错误的格式保存,要么保存在读取它的相同位置。后者并非如此。但是,我看不出我是如何给出错误格式的:在同一个 MSDN 页面上,给出了一个示例,其中 .bmp 以相同的方式转换为 .gif。
这与我保存到 MemoryStream 有关吗?这样做是为了我可以用转换后的文件覆盖原始文件。(请注意,.bmp 后缀是有意保留的。这应该不是问题,因为在保存最终文件之前出现异常。)
解决方案
在该Bitmap 构造函数的 MSDN 文档中,它说:
您必须在位图的生命周期内保持流打开。
同样的评论可以在 上找到Image.FromStream
。
因此,您的代码应该仔细处理它用于每个位图/图像的流的范围和生命周期。
结合所有以下代码正确处理这些流:
foreach (string path in files) {
using (var ms = new MemoryStream()) //keep stream around
{
using (var fs = new FileStream(path, FileMode.Open)) // keep file around
{
// create and save bitmap to memorystream
using(var bmp = new Bitmap(fs))
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
}
}
// write the PNG back to the same file from the memorystream
using(var png = Image.FromStream(ms))
{
png.Save(path);
}
}
}
推荐阅读
- php - 使用 PHP 和 mysql 连续引导 2 张卡片
- java - 如果'checked'属性不可用于使用isChecked / isSelected,如何使用selenium检查复选框的状态?
- python - 如何使用python获取linux目录/文件权限字符串
- powerbi - 如何将 PowerBi 中的小计从总和更改为平均值?
- google-analytics - Google Analytics UserID API 提取
- node.js - AdonisJS 单路打不开
- typescript - 将数组作为参数应用到 Date 构造函数
- c# - 查看模型结果的下拉列表
- chisel - 如何在 Chisel (regmap) 中遍历类似的寄存器定义
- php - 如何在 php 中包含变量值作为 url 的一部分