Multilingual Support with WASM

最終更新日:2024-09-03 17:00:39

この例では、C、C ++、Rust、Goなどの言語で記述されたコードをWebAssembly(WASM)形式にコンパイルし、Edge Cloud Apps関数内で実行して、画像のサイズ変更機能を実現する方法を示します。ユーザーはWebインターフェースを介して画像をアップロードし、目的の幅を指定すると、関数は事前にコンパイルされたWASMライブラリを呼び出して画像を処理し、サイズ変更されたバージョンを返します。

コード例

// 32MBのメモリでWebAssemblyモジュールをインスタンス化します
const wasm = require('./resizer.wasm', {memory: new WebAssembly.Memory({initial: 1024})});
const resizer = wasm.exports; // WASMモジュールからエクスポートされた関数にアクセスします

async function handleRequest(request) {
    let {pathname} = new URL(request.url.toLowerCase());
    if (pathname.endsWith('/'))  pathname = pathname.substring(0, pathname.length - 1);

    if (pathname === '/wasm-resizer.html') {
        // HTMLページを返します
        return new Response(HOMEPAGE, {headers: {"Content-Type": "text/html; charset=utf-8"}});
    } else {
        // 画像のサイズ変更リクエストを処理します
        return handleResize(request);
    }
}

// 画像のサイズ変更リクエストを処理します
async function handleResize(request) {
    const requestJSON = await request.json(); // リクエストパラメータを解析します
    if (!requestJSON.url) {
      return new Response('画像のURLを指定してください!'); // パラメータが不足している場合のエラー処理
    }
    const width = parseInt(requestJSON.width);
    if (isNaN(width) || width <= 0) {
      return new Response('有効な幅を入力してください!'); // 無効な幅の場合のエラー処理
    }

    // リクエストヘッダーを設定します
    const headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
                     'Accept': '*/*'};
    let response = await fetch(requestJSON.url, {cdnProxy: false, headers}); 

    // レスポンスが画像かどうかを確認します
    let type = response.headers.get("Content-Type") || "";
    if (!type.startsWith("image/")) {
        return new Response('レスポンスは画像ではありません!'); // 画像以外のレスポンスの場合のエラー処理
    }

    // 画像データをメモリに読み込みます
    let bytes = new Uint8Array(await response.arrayBuffer());

    // WASMモジュールのinit()関数を呼び出して、メモリスペースを割り当てます
    let ptr = resizer.init(bytes.byteLength);

    // WebAssemblyメモリに画像データをコピーします
    const memoryBytes = new Uint8Array(wasm.env.memory.buffer);
    memoryBytes.set(bytes, ptr);

    // WASMモジュールのresize()関数を呼び出して、画像のサイズを変更します
    let newSize = resizer.resize(bytes.byteLength, width);

    if (newSize == 0) {
        return new Response(`画像のサイズ変更に失敗しました!`);
    }

    // WebAssemblyメモリからサイズ変更された画像データを抽出します
    let resultBytes = memoryBytes.slice(ptr, ptr + newSize);

    // 新しいレスポンスを作成し、サイズ変更された画像データをクライアントに返します
    return new Response(resultBytes.buffer, {headers: {"Content-Type": "image/jpeg"}}); 
}

// HTMLページのコンテンツ
const HOMEPAGE = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>画像のサイズ変更</title>
    <style>
        // ... ページスタイル ...
    </style>
</head>
<body>
    <div class="container">
        <div class="input-container">
            <label for="imageUrl">元の画像URL(ノードがアクセスできない場合があります)</label>
            <input type="text" id="imageUrl" value="http://ctest.eca.wangsu.com/ECA-test/pet-shop-website-template/img/about.jpg">
        </div>
        <div class="input-container">
            <label for="imageWidth">サイズ変更後の幅(元の幅よりも小さくする必要があります)</label>
            <input type="text" id="imageWidth" value="365">
        </div>
        <button class="button" onclick="adjustImageSize()">サイズ変更</button>
        <div class="image-container" id="resultContainer"></div>
    </div>

    <script>
        // ... ページスクリプト ...
    </script>
</body>
</html>
`;
                    
addEventListener("fetch", event => {
    return event.respondWith(handleRequest(event.request));
});

注意

現在、Edge Cloud AppsはJavaScriptランタイム環境のみをサポートしていますが、C、C ++、Rust、Goなどの言語で記述されたコードをWebAssembly(WASM)形式にコンパイルし、Edge Cloud Apps関数内で実行できます。これにより、既存のコードアセットを再利用し、より高い実行効率を実現できます。