AWS Lambda Exception: Unable to load shared library 'libdl' when generating slide thumbnail (C#)

When calling GetThumbnail() in an AWS Lambda the code fails with the below exception

{
  "errorType": "AggregateException",
  "errorMessage": "One or more errors occurred. (The type initializer for 'Gdip' threw an exception.)",
  "stackTrace": [
    "at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)",
    "at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
  ],
  "cause": {
    "errorType": "TypeInitializationException",
    "errorMessage": "The type initializer for 'Gdip' threw an exception.",
    "stackTrace": [
      "at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, HandleRef scan0, IntPtr& bitmap)",
      "at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)",
      "at Aspose.Slides.Slide.GetThumbnail(Size imageSize)",
      "at \u0005   .\u0002(Size \u0002)",
      "at \u0005   .\u0002(Single \u0002, Single \u0003)",
      "at OfficeDocToImage.Function.ConvertPowerpointToImages(AmazonS3Client client, GetObjectResponse response, String s3Folder, String s3Bucket, OfficeDocToImageRequest request) in /.../udmOfficeDocToImage/src/OfficeDocToImage/Function.cs:line 93",
      "at OfficeDocToImage.Function.FunctionHandler(APIGatewayProxyRequest apiRequest, ILambdaContext context) in /.../udmOfficeDocToImage/src/OfficeDocToImage/Function.cs:line 69"
    ],
    "cause": {
      "errorType": "DllNotFoundException",
      "errorMessage": "Unable to load shared library 'libdl' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibdl: cannot open shared object file: No such file or directory",
      "stackTrace": [
        "at Interop.Libdl.dlopen(String fileName, Int32 flag)",
        "at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()",
        "at System.Drawing.SafeNativeMethods.Gdip..cctor()"
      ]
    }
  },
  "causes": [
    {
      "errorType": "TypeInitializationException",
      "errorMessage": "The type initializer for 'Gdip' threw an exception.",
      "stackTrace": [
        "at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, HandleRef scan0, IntPtr& bitmap)",
        "at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)",
        "at Aspose.Slides.Slide.GetThumbnail(Size imageSize)",
        "at \u0005   .\u0002(Size \u0002)",
        "at \u0005   .\u0002(Single \u0002, Single \u0003)",
        "at OfficeDocToImage.Function.ConvertPowerpointToImages(AmazonS3Client client, GetObjectResponse response, String s3Folder, String s3Bucket, OfficeDocToImageRequest request) in /.../udmOfficeDocToImage/src/OfficeDocToImage/Function.cs:line 93",
        "at OfficeDocToImage.Function.FunctionHandler(APIGatewayProxyRequest apiRequest, ILambdaContext context) in /.../udmOfficeDocToImage/src/OfficeDocToImage/Function.cs:line 69"
      ],
      "cause": {
        "errorType": "DllNotFoundException",
        "errorMessage": "Unable to load shared library 'libdl' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibdl: cannot open shared object file: No such file or directory",
        "stackTrace": [
          "at Interop.Libdl.dlopen(String fileName, Int32 flag)",
          "at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()",
          "at System.Drawing.SafeNativeMethods.Gdip..cctor()"
        ]
      }
    }
  ]
}

@deanvniekerk,

Thanks for contacting us. Can you please share source file along with sample code and complete environment details so that we may further investigate to help you out.

Hi,

The environment is the Amazon Linux image.

See example code below.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.S3;
using Amazon.S3.Model;
using Aspose.Slides;
using System.Drawing;
using Aspose.Slides.Export;
using System.IO;
using System.Drawing.Imaging;
using Aspose.Words;
using Aspose.Words.Saving;

// 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 OfficeDocToImage
{
    public class Function
    {
        public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apiRequest, ILambdaContext context)
        {
            var config = new AmazonS3Config() { };

            var request = JsonConvert.DeserializeObject<OfficeDocToImageRequest>(apiRequest.Body);

            var s3Bucket = Environment.GetEnvironmentVariable("targetBucket");
            var s3AwsUrl = Environment.GetEnvironmentVariable("AWS_URL_S3");

            Console.WriteLine("EnvironmentVariable:AWS_BUCKET -> " + s3Bucket);
            Console.WriteLine("EnvironmentVariable:AWS_URL_S3 -> " + s3AwsUrl);

            if (!string.IsNullOrEmpty(request.s3Bucket))
                s3Bucket = request.s3Bucket;

            if (!string.IsNullOrEmpty(s3AwsUrl))
            {
                config = new AmazonS3Config()
                {
                    ServiceURL = $"http://{s3AwsUrl}",
                    UseHttp = true,
                    ForcePathStyle = true,
                };
            }

            var client = new AmazonS3Client(config);

            var getObjectRequest = new GetObjectRequest()
            {
                BucketName = s3Bucket,
                Key = request.s3Key
            };

            var s3Folder = Path.GetDirectoryName(request.s3Key);

            //Pull down the office document
            using (var response = await client.GetObjectAsync(getObjectRequest))
            {
                var s3Keys = new List<string>();

                var extension = Path.GetExtension(request.s3Key);

                switch (extension)
                {
                    case ".pptx":
                        s3Keys = await ConvertPowerpointToImages(client, response, s3Folder, s3Bucket, request);
                        break;
                    default:
                        throw new Exception($"Unhandled Office Document Type: {extension}");
                }

                var officeDocToImageResponse = new OfficeDocToImageResponse() { s3Keys = s3Keys };

                return new APIGatewayProxyResponse
                {
                    Body = JsonConvert.SerializeObject(officeDocToImageResponse),
                    StatusCode = 200,
                    Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
                };
            }
        }

        private async Task<List<string>> ConvertPowerpointToImages(AmazonS3Client client, GetObjectResponse response, string s3Folder, string s3Bucket, OfficeDocToImageRequest request)
        {
            using (var presentation = new Presentation(response.ResponseStream))
            {
                var options = new NotesCommentsLayoutingOptions();

                //Generate full size images
                var images = presentation.GetThumbnails(options, 1, 1);

                var s3Keys = new List<string>();

                foreach (var image in images)
                {
                    var fileName = Guid.NewGuid().ToString();
                    var key = Path.Combine(s3Folder, fileName);

                    s3Keys.Add(key);

                    var stream = ResizeImageByWidth(image, request.width);

                    var putObjectRequest = new PutObjectRequest()
                    {
                        BucketName = s3Bucket,
                        Key = key,
                        InputStream = stream
                    };

                    await client.PutObjectAsync(putObjectRequest);
                }

                return s3Keys;
            }
        }

        private MemoryStream ResizeImageByWidth(Bitmap image, int newWidth)
        {
            var stream = new MemoryStream();

            var percentWidth = ((float)image.Width / (float)newWidth);

            var bitmap = new Bitmap(newWidth, (int)(image.Height / percentWidth));
            var graphics = Graphics.FromImage(bitmap);

            graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            graphics.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height);
            graphics.Dispose();

            bitmap.Save(stream, ImageFormat.Png);

            return stream;
        }
    }
}

@deanvniekerk,

I have observed the issue shared by you and like to share that an issue with ID SLIDESNET-41073 has already been created in our issue tracking system to further investigate and resolve the issue. This thread has been linked with the issue so that you may be notified once the issue will be fixed.

I am having this same issue using Aspose.Slides for .NET within an .net core docker container. I tried to install the missing library but that just changed the error to something else. Is there a resolution for this?

@kevin.brashear.gartn,

I like to share that the associated issue is under investigation and we request for your patience till the time further feedback is shared by team after resolution of the issue.

The issues you have found earlier (filed as SLIDESNET-41073) have been fixed in this update. This message was posted using Bugs notification tool.