使用System.Drawing时发生崩溃,OutOfMemoryException,一般错误

时间:2018-09-13 12:52:04

标签: c# .net image-processing gdi+ .net-4.6.1

我正在C#中运行一项cron作业,该作业需要200,000张图像并将其转换为1位图像。在执行此作业期间,有时会process crashes(即使我有全局try catch),有时对于某些图像(不是全部),它会抛出OutOfMemoryException,有时对于某些图像,它会抛出A generic error occurred in GDI

        int pageSize = 1000;
        for (int pageNumber = 0; pageNumber < 200; pageNumber++)
        {
            var imageUrls = allIMageUrls.Skip(pageSize * pageNumber).Take(pageSize).ToList();
            var counter = 0;
            var total = imageUrls.Count;
            Logger.Log($"Page Number : {pageNumber}");
            var failedImageUrls = new System.Collections.Concurrent.ConcurrentBag<string>();
            Parallel.ForEach(imageUrls, imageUrl =>
            {
                try
                {
                    Interlocked.Increment(ref counter);
                    var image = _httpService.DownloadImage(imageUrl);
                    if (image != null && image.Length > 0)
                    {
                        var oneBitImage = ConvertToOnebitFaxGroup4(contract);
                        _httpService.UploadImage(image, oneBitImage);
                        oneBitImage = null;
                        image  = null;
                    }
                }
                catch (Exception ex)
                {
                    failedImageUrls.Add(imageUrl);                        
                    Logger.Log(ex);
                }
            });

这是一次过程。我添加了分页,以便在崩溃时可以从该页面重新启动,而不是从头开始。

 public static class ImageProcessor
 {

    static ImageCodecInfo _codecInfo;
    static EncoderParameters _encoderParameters;

    static ImageProcessor()
    {
        foreach (var codec in ImageCodecInfo.GetImageEncoders())
        {
            if (codec.MimeType == "image/tiff")
            {
                _codecInfo = codec;
                break;
            }
        }
        _encoderParameters = new EncoderParameters(2);
        _encoderParameters.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
        _encoderParameters.Param[1] = new EncoderParameter(Encoder.ColorDepth, (long)1);
    }

    public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
    {
        using (var memoryStream = new MemoryStream(bytes))
        {
            var image = Image.FromStream(memoryStream);
            var pData = Marshal.AllocHGlobal(bytes.Length);
            Marshal.Copy(bytes, 0, pData, bytes.Length);
            var bytesPerLine = (image.Width + 31) / 32 * 4; 
            var img = new Bitmap(image.Width, image.Height, bytesPerLine, PixelFormat.Format1bppIndexed, pData);
            using (var ms = new MemoryStream())
            {
                image.Save(ms, _codecInfo, _encoderParameters);
                img.Dispose();
                Marshal.FreeHGlobal(pData);
                return ms.ToArray();
            }
        }
    }

已更新:

    public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
    {
        using (var memoryStream = new MemoryStream(bytes))
        {
            using (var image = Image.FromStream(memoryStream))
            {
                var pData = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, pData, bytes.Length);
                var bytesPerLine = (image.Width + 31) / 32 * 4;
                using (var img = new Bitmap(image.Width, image.Height, bytesPerLine, PixelFormat.Format1bppIndexed, pData))
                {
                    using (var ms = new MemoryStream())
                    {
                        img.Save(ms, _codecInfo, _encoderParameters);
                        Marshal.FreeHGlobal(pData);
                        return ms.ToArray();
                    }
                }
            }
        }
    }

Update2

    public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
    {
        using (var memoryStream = new MemoryStream(bytes))
        {
            using (var image = Image.FromStream(memoryStream))
            {
                using (var ms = new MemoryStream())
                {
                    image.Save(ms, _codecInfo, _encoderParameters);
                    return ms.ToArray();
                }
            }
        }
    }

0 个答案:

没有答案