版权声明:本文为博主原创文章,转载请注明原文链接。 https://blog.csdn.net/crf_moonlight/article/details/81129995
C# WPF, System.Drawing.Bitmap.Save()
本来保存图片好好的, 今天保存图片就崩了. 因为图片尺寸大概是”80000px * 3500px
“, 所以第一反应就是图片太大没法保存.
但摆渡发现好像一般有三个原因
- 没有写权限
- 路径不存在
- 文件的生存周期问题
因为我是在内存中直接创建的Bitmap
, 之前保存的都好好的, 所以这三种情况都不符合, 但也得试试, 瞎折腾了一气没有卵用
然后想到转换一下到另外一种Image
格式行不行?
IntPtr hBitmap = _nBitmap.GetHbitmap();
var nImage = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap, IntPtr.Zero, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(nImage));
using (var stream = new FileStream(_filename, FileMode.Create))
{
encoder.Save(stream);
}
因为System.Windows
和System.drawing
名称空间的类名有重合, 所有显得很乱. 果然有变化了, 抛出异常, 大概意思是”超出解析器大小限制”, 简单的说就是文件太大了, 把图片分几块保存呗…
private static void DrawAndSave(string filename)
{
using (Bitmap _bitmap = new Bitmap(width, height))
{
_bitmap.SetResolution(Dpi, Dpi);
var _g = Graphics.FromImage(_bitmap);
_g.FillRectangle(backgroundBrush, new Rectangle(0, 0, width, height));
DrawTitle(_g);
for (var _i = 0; _i < nodes.Count; _i++)
{
DrawNode(nodes[_i], _g);
}
var _startPoint = 0;
var _unsavedPixels = width;
var _fileNumber = Math.Ceiling((double)width / WIDTH_LIMIT);
var _filenameSuff = $"{Path.GetDirectoryName(filename)}\\{Path.GetFileNameWithoutExtension(filename)}";
for (var i = 0; i < _fileNumber; i++)
{
var _filename = $"{_filenameSuff}_{i}.png";
var _width = _unsavedPixels > WIDTH_LIMIT ? WIDTH_LIMIT : _unsavedPixels;
using (var _nBitmap = new Bitmap(_width, height))
{
_nBitmap.SetResolution(Dpi, Dpi);
var _nG = Graphics.FromImage(_nBitmap);
_nG.DrawImage(_bitmap, 0, 0, new Rectangle(_startPoint, 0, _width, height), GraphicsUnit.Pixel);
_nBitmap.Save(_filename);
}
_startPoint += _width;
_unsavedPixels -= _width;
}
}
}
其中private static int WIDTH_LIMIT = 30000;
… OK了
最坑的是一开始设置为40000, 就不OK… 白折腾这么久