我正在尝试根据用户上传的图像自动生成缩略图,但始终收到“内存不足”的异常.
据我了解,当您指定图像以外的开始位置或宽度/高度时,会抛出内存不足异常,即使我这样做

var rct = new Rectangle(5, 5, 10, 10);
var whatever = bitmap.Clone(rct, bitmap.PixelFormat);

在800×900像素的图像上,我仍然会收到“内存不足”异常,我无法弄清楚问题出在哪里,并且由于与OOM异常有关的所有内容,我也无法真正从其他线程中获得任何好的答案.超出图像边界的错误.
有人对此有解释或解决方案吗?

编辑:更多上下文

图像循环.


foreach (var blob in fileInfoList)
{
    var blockBlobName = CheckExistence(BaseBlobUrl, blob.FileName, blob.FileNameWithoutExtension);

    var image = new Image()
    {
        BlobUrl = Path.Combine(BaseBlobUrl, blockBlobName),
        FullName = blob.FileName,
        FileName = blob.FileNameWithoutExtension,
        BlockBlobName = blockBlobName,
        OwningOrganizationId = CurrentUser.UserOrganization.OrganizationId,
        ThumbnailUrl = CreateThumbnail(blob.File, blockBlobName),
        Name = "Whatever"
    };

    blobList.Add(image);

    RepositoryFactory.AzureStorageRepository.SaveImage(blob.File, blockBlobName, blob.ContentType, CurrentUser.UserOrganization.Organization.Id);
}

列表中每个图像所调用的生成缩略图的方法.

public string CreateThumbnail(byte[] b, string parentImageName)
    {
        Bitmap bmp;

        using (var ms = new MemoryStream(b))
        {
            bmp = new Bitmap(ms);
        }

        Bitmap thumbnail = bmp;

        Rectangle rect = new Rectangle(5, 5, 10, 10);

        if (bmp.Width > bmp.Height)
            thumbnail = bmp.Clone(rect, bmp.PixelFormat);
        else if (bmp.Height > bmp.Width)
            thumbnail = bmp.Clone(new Rectangle((bmp.Height/2) - (bmp.Width/2), 0, bmp.Width, bmp.Width), bmp.PixelFormat);

        byte[] bmpArray = new byte[0];

        using (var ms = new MemoryStream())
        {
            finalCrop.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            ms.Close();

            bmpArray = ms.ToArray();
        }

        var name = "Thumbnail_" + parentImageName;

        RepositoryFactory.AzureStorageRepository.SaveThumbnail(bmpArray, name, "jpg/image", CurrentUser.UserOrganization.Organization.Id);

        return BaseBlobUrl + "thumbnails/" + name;


    }

解决方法:

我认为您遇到的问题是需要处理位图.如果在不释放其底层非托管内容(即被处置)的情况下收集了垃圾,那么该内存将无法恢复…

还要注意,您将需要同时放置两个位图.最好的办法是将它们包装在using中,如下所示:

        using (var ms = new MemoryStream(b))
        {
            using (Bitmap bmp = new Bitmap(ms))
            using (Bitmap thumbnail = bmp)
            {

                Rectangle rect = new Rectangle(5, 5, 10, 10);

                if (bmp.Width > bmp.Height)
                    thumbnail = bmp.Clone(rect, bmp.PixelFormat);
                else if (bmp.Height > bmp.Width)
                    thumbnail = bmp.Clone(new Rectangle((bmp.Height / 2) - (bmp.Width / 2), 0, bmp.Width, bmp.Width), bmp.PixelFormat);

                byte[] bmpArray = new byte[0];

                using (var ms = new MemoryStream())
                {
                    finalCrop.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    ms.Close();

                    bmpArray = ms.ToArray();
                }

                var name = "Thumbnail_" + parentImageName;

                RepositoryFactory.AzureStorageRepository.SaveThumbnail(bmpArray, name, "jpg/image", CurrentUser.UserOrganization.Organization.Id);

                return BaseBlobUrl + "thumbnails/" + name;
            }
        }

值得注意的是,即使抛出异常,使用也会在目标上调用Dispose()(因此,最终类型功能与@Scott Chamberlain答案相同)

标签: c, asp-net, net

相关文章推荐

添加新评论,含*的栏目为必填