"System.Runtime.InteropServices.ExternalException GDI+中发生一般性错误的解决办法"的另一种原因

版权声明:本文为博主原创文章,转载请注明原文链接。 https://blog.csdn.net/crf_moonlight/article/details/81129995

C# WPF, System.Drawing.Bitmap.Save()本来保存图片好好的, 今天保存图片就崩了. 因为图片尺寸大概是”80000px * 3500px
“, 所以第一反应就是图片太大没法保存.

但摆渡发现好像一般有三个原因

  1. 没有写权限
  2. 路径不存在
  3. 文件的生存周期问题

因为我是在内存中直接创建的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.WindowsSystem.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… 白折腾这么久

猜你喜欢

转载自blog.csdn.net/crf_moonlight/article/details/81129995
今日推荐