Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

オーバーレイと透かしを描画する

最終更新 Markdown で表示Agent セットアップ

Workers で、テキスト、透かし、ロゴをほかの画像の上に描けます。オーバーレイは透明度、位置指定、合成モードに対応しています。

Worker でオーバーレイを描画する方法は 2 つあります。

cf.image で描画する

Workers の fetch() サブリクエスト でオーバーレイを描画するには、cf.image オプションに draw 配列を追加します。

各エントリは画像またはテキストを描画します。

  • 画像url に画像の絶対 URL を指定します。widthheightfitblurrotate などの 最適化パラメーター を適用できます。
  • テキストtext に描画する文字列を指定します。バインディングの .text() メソッドと同じ fontcolorsize オプションでスタイルを設定します。利用可能なオプション、デフォルト、制限は .text() を参照してください。

オーバーレイは配列の順に描画されます。最後のエントリが最前面のレイヤーになります。

export default {
	async fetch(request) {
		const imageURL = "https://example.com/image.png";

		return fetch(imageURL, {
			cf: {
				image: {
					width: 800,
					height: 600,
					draw: [
						{
							url: "https://example.com/branding/logo.png",
							bottom: 5,
							right: 5,
							fit: "contain",
							width: 100,
							height: 50,
							opacity: 0.8,
						},
						{
							text: "HELLO",
							font: { url: "https://example.com/font.otf" },
							color: "#223E49",
							size: 96,
							top: 40,
						},
					],
				},
			},
		});
	},
};

Images バインディングで描画する

Images バインディング は、チェーン可能な .draw() メソッドで画像の上にオーバーレイを描画します。.draw() を複数回チェーンすると、複数のオーバーレイを重ねられます。

第 1 引数にオーバーレイ、第 2 引数に描画オプションを渡します。オーバーレイは画像またはテキストです。

  • 画像 — 画像のバイト列、または .input() チェーンを渡します。オーバーレイ画像に 最適化パラメーター を適用するには、第 1 引数に .transform() を含む .input() チェーンを渡します。
  • テキスト.text() で作成したハンドルを渡します。フォント、色、サイズは .text()options 引数で設定します。利用可能なオプション、デフォルト、制限は .text() を参照してください。
export default {
	async fetch(request, env) {
		const img = await fetch("https://example.com/base.png");
		const watermark = await fetch("https://example.com/overlay.png");

		const response = (
			await env.IMAGES.input(img.body)
				.draw(env.IMAGES.input(watermark.body).transform({ width: 100 }), {
					bottom: 10,
					right: 10,
					opacity: 0.5,
				})
				.draw(
					env.IMAGES.text("HELLO", {
						font: { url: "https://example.com/font.otf" },
						color: "#223E49",
						size: 96,
					}),
					{ top: 40 },
				)
				.output({ format: "image/avif" })
		).response();

		return response;
	},
};

オプション

出力画像の寸法は、常にベース画像で決まります。オーバーレイはそのキャンバス上に描画されます。

位置とブレンドには、次の描画専用オプションを使えます。

url

cf.image で描画するときのオーバーレイ画像の絶対 URL です。url は画像オーバーレイにのみ適用されます。テキストを描画する場合は、代わりに draw 配列の text エントリでオーバーレイを作成します。

対応画像形式 を受け付けます。透かしや非矩形のオーバーレイには、PNG または WebP を使います。

バインディングで画像オーバーレイを描画する場合、オーバーレイは URL ではなく画像バイト列または .input() チェーンとして渡します。Images バインディングで描画する を参照してください。

text

cf.image で描画するときに、テキスト文字列をオーバーレイとして描画します。Images バインディングで描画する場合は、代わりに .text() でテキストオーバーレイを作成します。

fontcolorsize オプションでテキストをスタイルします。これらは cf.image のテキストエントリと、バインディングの .text() メソッドの両方に適用されます。利用可能なオプション、デフォルト、制限は .text() を参照してください。

widthheight

cf.image で描画するときのオーバーレイ画像の最大寸法を設定します。これらのオプションは画像オーバーレイにのみ適用されます。テキストオーバーレイの寸法は、文字列とスタイルで決まります。

整数(ピクセル)または、ベース画像の寸法に対する割合を表す 0 から 1 の小数を受け付けます。たとえば height:0.25 は、オーバーレイの高さをベース画像の高さの 25% にします。

オーバーレイ画像のリサイズとクロップは fitgravity で制御します。

Images バインディングで描画する場合、オーバーレイ画像の寸法は .transform() メソッドで設定できます。

repeat

オーバーレイを画像全体にタイルするかどうかを決めます。

次の値を受け付けます。

  • true — オーバーレイをタイルして領域全体を覆います。透かしに便利です。
  • x — 水平方向にのみタイルします。
  • y — 垂直方向にのみタイルします。

topleftbottomright

指定した端からのオフセット(ピクセル)でオーバーレイの位置を設定します。0 は端にぴったり揃えます。位置を指定しない場合、オーバーレイは中央に配置されます。

たとえば { bottom: 0, right: 10 } は、右下隅にオーバーレイを置き、右端から 10 ピクセル内側にします。

leftright の両方、または topbottom の両方を設定するとエラーになります。

opacity

オーバーレイの不透明度を設定します。0.0(完全に透明)から 1.0(完全に不透明)の小数を受け付けます。たとえば opacity: 0.5 は半透明にします。

composite

Porter-Duff 合成演算 で、オーバーレイをベース画像とどうブレンドするかを制御します。デフォルトは over です。

合成モードが影響するのは、オーバーレイのバウンディングボックス内だけです。この領域の外では、ベース画像は常に保持されます。

次の値を受け付けます。

over

オーバーレイをベース画像の上に描画します。これがデフォルトの composite 動作です。

重なる部分はオーバーレイがベースを覆います。重ならない部分は両方の画像が見えます。

composite=over の出力

in

ベース画像が不透明な箇所にだけオーバーレイを表示します。オーバーレイの透明ピクセルがベース画像と重なると、ベース画像のその部分も透明になります。

composite=in の出力

atop

ベース画像が不透明な箇所にだけ、オーバーレイをベース画像の上に描画します。オーバーレイはベース画像の形状にクリップされます。

オーバーレイの透明ピクセルがベース画像と重なっても、ベース画像は見えるままです(in とは異なります)。

composite=atop の出力

out

ベース画像が透明な箇所にだけオーバーレイを表示します。オーバーレイのバウンディングボックス内では、ベース画像の不透明な領域が透明になります。

composite=out の出力

xor

一方が透明な箇所だけを表示します。重なる不透明領域は透明になります。角丸 やカスタム形状の作成に使えます。

composite=xor の出力

lighter

両方の画像の色値を加算し、重なる領域を明るくします。

composite=lighter の出力

透かし

cf.image を使い、半透明の透かしを画像全体にタイルします。

fetch(imageURL, {
	cf: {
		image: {
			draw: [
				{
					url: "https://example.com/watermark.png",
					repeat: true,
					opacity: 0.2,
				},
			],
		},
	},
});

隅にロゴを置く

cf.image を使い、右下隅にロゴを配置します。

fetch(imageURL, {
	cf: {
		image: {
			draw: [
				{
					url: "https://example.com/logo.png",
					bottom: 5,
					right: 5,
				},
			],
		},
	},
});

複数のオーバーレイ

cf.image を使い、1 回のリクエストで複数のオーバーレイを組み合わせます。配列の順に描画され、最後のエントリが最前面のレイヤーになります。

fetch(imageURL, {
	cf: {
		image: {
			draw: [
				{
					url: "https://example.com/watermark.png",
					repeat: true,
					opacity: 0.2,
				},
				{ url: "https://example.com/play-button.png" },
				{ url: "https://example.com/logo.png", bottom: 5, right: 5 },
			],
		},
	},
});

角丸

画像から角を丸く切り取ります。各角にコーナーマスクを描画し、位置に合わせて回転します。xor が重なったピクセルを取り除きます。

次の例は、Images バインディング で行う方法です。

const image = await fetch("https://example.com/photo.png");
const mask = await fetch("https://example.com/corner-mask.png");

let [topLeft, topRight] = mask.body.tee();
let bottomLeft, bottomRight;
[topLeft, bottomLeft] = topLeft.tee();
[topLeft, bottomRight] = topLeft.tee();

const output = await env.IMAGES.input(image.body)
	.draw(env.IMAGES.input(topLeft).transform({ rotate: 0 }), {
		left: 0,
		top: 0,
		composite: "xor",
	})
	.draw(env.IMAGES.input(topRight).transform({ rotate: 90 }), {
		right: 0,
		top: 0,
		composite: "xor",
	})
	.draw(env.IMAGES.input(bottomRight).transform({ rotate: 180 }), {
		bottom: 0,
		right: 0,
		composite: "xor",
	})
	.draw(env.IMAGES.input(bottomLeft).transform({ rotate: 270 }), {
		bottom: 0,
		left: 0,
		composite: "xor",
	})
	.output({ format: "image/png" });

return output.response();

役に立ちましたか?