我正在尝试在AWS Lambda中上载一个执行一些图像处理功能的功能。
我正在使用Visual Studio 2017和适用于Visual Studio的AWS Toolkit来开发该功能并将其上传到AWS Lambda。 AWS Lambda正在使用.Net Core 2.1(C#/ PowerShell)运行时,并将Handler设置为FunctionHandler函数。
我要上传到AWS Lambda的函数如下:
using System;
using System.IO;
using System.Net;
using System.Drawing;
using System.Drawing.Imaging;
using Amazon.Lambda.Core;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
namespace LambdaTest
{
public class Function
{
public object FunctionHandler(MapsAPI input)
{
try
{
// Form the request for each tile
Uri uri = new Uri(input.GetFullUri(), UriKind.Absolute);
Bitmap bitOutput = null;
string contentType = string.Empty;
try
{
WebRequest req = WebRequest.Create(uri);
using (WebResponse response = req.GetResponse())
{
// Save content type to use later when passing bitmap on to webpage
contentType = response.ContentType;
// The response stream is the map tile image to display
using (Stream stream = response.GetResponseStream())
{
bitOutput = new Bitmap(stream);
// We will apply a watermark for higher zoom levels
// coresponding to VML and MM Topo
if (Convert.ToDouble(input.z) >= 9.0)
{
// Create a Graphics object from the bitmap instance
using (Graphics gphx = Graphics.FromImage(bitOutput))
{
// Create a font
Font fontWatermark = new Font("Verdana", 16, FontStyle.Bold, GraphicsUnit.Pixel);
// Indicate that the text should be centered
StringFormat stringFormat = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
// Add the watermark...
gphx.DrawString(
"Mapping",
fontWatermark,
new SolidBrush(Color.FromArgb(100, Color.Navy)),
new Rectangle(10, 10, bitOutput.Width - 10, bitOutput.Height - 10),
stringFormat);
}
}
}
}
}
catch (Exception ex)
{
string msg = ex.Message;
string msg2 = ex.InnerException.Message;
if (bitOutput != null) { bitOutput.Dispose(); }
TileStream output = new TileStream
{
contentType = msg + " : " + msg2
};
return output;
}
ImageFormat format;
switch (contentType)
{
case "image/png":
format = ImageFormat.Png;
break;
case "image/gif":
format = ImageFormat.Gif;
break;
default:
format = ImageFormat.Jpeg;
break;
}
if (bitOutput != null)
{
TileStream output = new TileStream
{ contentType = contentType };
bitOutput.Save(output.imageStream, format);
bitOutput.Dispose();
return output;
}
}
catch (Exception ex)
{ return null; }
}
}
}
如您所见,该代码利用了System.Drawing。我意识到AWS Lambda并未实现System.Drawing类,因此我必须使用替代来实现绘图功能。
我最初安装了System.Drawing.Common NuGet软件包,但是当我尝试运行Lambda函数时,它返回了异常错误:
'“” Gdip“的类型初始值设定项引发了异常。:无法加载 共享库'libdl'或其依赖项之一。'
在线查看后,其中一种解决方案建议尝试使用CoreCompat.System.Drawing.v2代替我的绘图工具。
我安装了此软件包,但遇到了另一个异常:
“ System.Drawing.GDIPlus”的类型初始值设定项引发了异常。 :无法加载共享库'gdiplus'或其依赖项之一
在线解决方案告诉我,我需要为此软件包下载Linux Runtime才能使其成功执行,因此我从NuGet下载了runtime.linux-x64.CoreCompat.System.Drawing软件包。
安装该软件包并更新AWS Lambda之后,我现在收到以下错误:
{“ errorMessage”:“ RequestId:ded846b8-a3e2-4f24-90fb-ef0e9a688ba8 在完成请求之前,流程已退出”}
这表明代码现在甚至都没有运行。
关于为什么要安装runtime.linux软件包的任何解决方案似乎都会阻止代码在AWS Lambda或我可以尝试用于System.Drawing函数的任何其他NuGet软件包上编译/运行。
非常感谢!
编辑: 每当发生错误时,这是我的函数的CloudWatch日志:
09:55:06
START RequestId: abeab72f-b522-4d2b-b839-939c648d8f02 Version: $LATEST
09:55:08
END RequestId: abeab72f-b522-4d2b-b839-939c648d8f02
09:55:08
REPORT RequestId: abeab72f-b522-4d2b-b839-939c648d8f02 Duration: 2065.84 ms Billed Duration: 2100 ms Memory Size: 512 MB Max Memory Used: 120 MB
09:55:08
RequestId: abeab72f-b522-4d2b-b839-939c648d8f02 Process exited before completing request