AWS Lambda(C#)でMagick.NETを使ってみる
はじめに
「Magick.NET」は「ImageMagick」の.NET向けライブラリです。
ImageMagick(イメージマジック)は画像を操作したり表示したりするためのソフトウェアスイートである。GIF、JPEG、JPEG 2000、PNG、PDF、Photo CD、TIFF、DPXなど100種類以上の画像ファイルフォーマットに対応している。GPL互換でより制限が緩い独自ライセンスが適用されている。
出典: フリー百科事典『ウィキペディア(Wikipedia)』
今回は、「Magick.NET」をAWS Lambda上で使えるか試してみようと思います。
実装
あらかじめNugetから「Magick.NET(AnyCPU)」パッケージをインストールしておきます。今回はQ8を選択しました。
また、Lambdaプロキシ統合を使用して動作確認をするため「APIGatewayEvents」パッケージも追加インストールしました。

以下、ソースコードのサンプルです。SVG(XML)形式でサンプル画像を作成し、Magick.NETを用いてPNG形式に変換後、呼び出し元のAPI Gatewayへ返却しています。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;
using ImageMagick;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace AWSLambda7
{
public class Function
{
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
{
MagickReadSettings settings = new MagickReadSettings();
settings.Format = MagickFormat.Svg;
MagickImage img = new MagickImage(System.Text.Encoding.UTF8.GetBytes(GetSampleSVG()), settings);
img.Format = ImageMagick.MagickFormat.Png;
var body = Convert.ToBase64String(img.ToByteArray());
img.Dispose();
var myHeaders = new Dictionary<string, string>();
myHeaders.Add("Content-Type", "image/png");
myHeaders.Add("Content-Disposition", "attachment; filename=sample.png");
var response = new APIGatewayProxyResponse
{
StatusCode = 200
,
Body = body
,
IsBase64Encoded = true
,
Headers = myHeaders
};
return response;
}
private string GetSampleSVG()
{
int layer_x = 8;
int layer_y = 8;
int size = 16;
int vx = layer_x * size;
int vy = layer_y * size;
string svg = "";
svg += "<svg xmlns=\"http://www.w3.org/2000/svg\"";
svg += " xmlns:xlink=\"http://www.w3.org/1999/xlink\"";
svg += " viewBox=\"0 0 " + vx + " " + vy + "\" ";
svg += ">";
for (int y = 0; y < layer_y; y++)
{
for (int x = 0; x < layer_x; x++)
{
int gx = x * size;
int gy = y * size;
if ( (x+y) % 2 == 0 )
{
svg += "<rect x=\"" + gx.ToString() + "\" y=\"" + gy.ToString() + "\" width=\"" + size + "\" height=\"" + size + "\" fill=\"black\" />";
}
}
}
svg += "</svg>";
return svg;
}
}
}
早速上記Lambda関数をパブリッシュし、トリガーにAPI Gatewayを追加してみます。

ここで注意点です。
AWS Lambda プロキシ統合からバイナリメディアを返すには、base64 で Lambda 関数からのレスポンスをエンコードします。また、API のバイナリメディアタイプを設定する必要があります。
出典:Lambda プロキシ統合からバイナリメディアを返す – Amazon API Gateway
API Gatewayの設定画面を開き、「バイナリメディアタイプ」を設定します。今回は”*/*”(すべてのコンテンツタイプ)を設定しました。
設定保存後、APIのデプロイを忘れずにしましょう。

動作確認
ブラウザからエンドポイントのURLをたたくと、sample.pngファイルがダウンロードできます。

ファイルを開き、下記のような画像が表示されれば動作確認OKです。

以上です。
投稿者プロフィール

- 東京在住のフリーランスエンジニア
最新の投稿
AWS2020.11.05AWS CLI コマンドまとめ ~S3編~
AWS2020.11.02AWS コマンドラインインターフェイス(CLI)をインストールする~Windows編~
その他2020.10.30Chromeでクロスドメインiframe内の要素にアクセスする
AWS2020.10.29AWS API GatewayのREST APIでモックを作成する