[英]DrawingCore exception in azure function c# .net
未處理的異常: System.MemberAccessException :
Object is busy and cannot state allow this operation [GDI+ status: ObjectBusy]
at System.DrawingCore.GDIPlus.CheckStatus(Status status)
at System.DrawingCore.Image.Dispose(Boolean disposing)
at System.DrawingCore.Image.Finalize()
以下代碼偶爾會發生此錯誤。 我正在使用 sautinsoft 庫,而 imageFormat 是 System.DrawingCore.Imaging。
using (Stream fs = pdfFile.OpenReadStream())
{
await Task.Run(() => _pdfFocus.OpenPdf(fs));
if (_pdfFocus.PageCount > 0)
{
_pdfFocus.ImageOptions.ImageFormat = imageFormat;
_pdfFocus.ImageOptions.Dpi = 100;
_pdfFocus.ImageOptions.JpegQuality = 90;
for (int i = 1; i <= _pdfFocus.PageCount; i++)
{
await Task.Run(() => pdfPagesAsImageFileList.Add(_pdfFocus.ToImage(i)));
}
}
Task.WaitAll();
}
就像 Marc 所說的 azure 有沙箱限制,並且大多數將 pdf 轉換為圖像的 .net 包需要 GDI,這不受支持。 現在我只找到一個包來使用 .net 來實現它。 您可以嘗試使用GhostScript和Magick.NET-Q16-AnyCPU來實現它。
安裝Ghostscript
,您將在 bin 文件夾中獲得gsdll32.dll
文件。 下面是我的測試代碼,將02.pdf和gsdll32.dll復制到kudu wwwroot
文件夾下。
using System.Net.Http;
using ImageMagick;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
namespace FunctionApp6
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log,ExecutionContext context)
{
log.Info("C# HTTP trigger function processed a request.");
MagickNET.SetGhostscriptDirectory(context.FunctionAppDirectory);
log.Info(context.FunctionAppDirectory);
MagickReadSettings settings = new MagickReadSettings();
// Settings the density to 300 dpi will create an image with a better quality
settings.Density = new Density(300, 300);
using (MagickImageCollection images = new MagickImageCollection())
{
log.Info(context.FunctionAppDirectory + "\\02.pdf");
// Add all the pages of the pdf file to the collection
images.Read(context.FunctionAppDirectory+"\\02.pdf", settings);
int page = 1;
foreach (MagickImage image in images)
{
log.Info(context.FunctionAppDirectory + "\\outpng" + page + ".png");
// Write page to file that contains the page number
image.Write(context.FunctionAppDirectory + "\\outpng" + page + ".png");
// Writing to a specific format works the same as for a single image
//image.Format = MagickFormat.Ptif;
//image.Write(SampleFiles.OutputDirectory + "Snakeware.Page" + page + ".tif");
page++;
}
}
log.Info("convert finish");
}
}
}
這是天藍色的結果圖片。
Azure Functions 在安全環境(也稱為沙箱)中運行。 這個沙箱有很多限制,所有限制都在這里描述: https : //github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox
在您的特定情況下,您受到限制,因為該過程無法訪問上面鏈接的頁面中提到的 GDI32:
為了徹底減少攻擊面,沙箱阻止了幾乎所有的 Win32k.sys API 被調用,這實際上意味着大部分 User32/GDI32 系統調用被阻止。 對於大多數應用程序,這不是問題,因為大多數 Azure Web 應用程序不需要訪問 Windows UI 功能(畢竟它們是 Web 應用程序)。
有多個庫用於將 HTML 轉換為 PDF。 許多 Windows/.NET 特定版本利用 IE API,因此廣泛利用 User32/GDI32。 這些 API 大部分都在沙箱中被阻止(無論計划如何),因此這些框架在沙箱中不起作用。
有一些框架沒有廣泛利用 User32/GDI32(例如 wkhtmltopdf),我們正在努力在 Basic+ 中啟用這些,就像啟用 SQL 報告一樣。
您可能需要找到一種替代方法來創建 PDF 文件或將計算移到 Azure Functions 之外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.