INTEGRITY Dokumentace

Generování náhledů YouTube pomocí Workers a Cloudflare Image Resizing

V tomto tutoriálu se naučíte, jak programově vygenerovat vlastní miniaturu pro YouTube pomocí Cloudflare Workers a Cloudflare Image Resizing. Vlastní miniaturu pro YouTube můžete chtít vygenerovat proto, abyste si přizpůsobili její design, výzvy k akci a obrázky, které mají přilákat více diváků ke sledování vašeho videa.

Tento návod vám pomůže pochopit, jak pracovat s Obrázky,Změna velikosti obrázků a Cloudflare Workers.

Než začnete

Všechny návody předpokládají, že jste již dokončili Úvodní návod, který vás provede nastavením účtu Cloudflare Workers, C3, a Wrangler.

Než začnete postupovat podle tohoto tutoriálu, ověřte, že máte Node, Cargo a Wrangler nainstalovaný na vašem počítači.

Studijní cíle

V tomto tutoriálu se naučíte, jak:

Nahrajte svůj obrázek

Chcete-li vygenerovat vlastní miniaturu, musíte nejprve nahrát obrázek na pozadí do Cloudflare Images. Ten pak poslouží jako obrázek, který použijete pro transformace generující miniatury.

Cloudflare Images umožňuje rychle a bezpečně ukládat, měnit velikost, optimalizovat a doručovat obrázky. Pro začátek nahrajte obrázky do dashboardu Cloudflare, nebo použijte Upload API.

Nahrání přes dashboard

Chcete-li nahrát obrázek pomocí Cloudflare dashboardu:

  1. V dashboardu Cloudflare přejděte na Transformace stránce.

    Přejděte na Transformace ↗
  2. Použijte Quick Upload abyste buď přetáhli obrázek, nebo klikli a vybrali soubor z místních souborů.

  3. Po nahrání obrázku si jej zobrazte pomocí vygenerované adresy URL.

Nahrání přes API

Chcete-li nahrát obrázek pomocí Nahrání přes URL API si prohlédněte příklad níže:

curl --request POST \
 --url https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/images/v1 \
 --header 'Authorization: Bearer <API_TOKEN>' \
 --form 'url=<PATH_TO_IMAGE>' \
 --form 'metadata={"key":"value"}' \
 --form 'requireSignedURLs=false'

Poté obdržíte odpověď podobnou této:

{
	"result": {
		"id": "2cdc28f0-017a-49c4-9ed7-87056c83901",
		"filename": "image.jpeg",
		"metadata": {
			"key": "value"
		},
		"uploaded": "2022-01-31T16:39:28.458Z",
		"requireSignedURLs": false,
		"variants": [
			"https://imagedelivery.net/Vi7wi5KSItxGFsWRG2Us6Q/2cdc28f0-017a-49c4-9ed7-87056c83901/public",
			"https://imagedelivery.net/Vi7wi5KSItxGFsWRG2Us6Q/2cdc28f0-017a-49c4-9ed7-87056c83901/thumbnail"
		]
	},
	"success": true,
	"errors": [],
	"messages": []
}

Nyní, když jste obrázek nahráli, jej použijete jako pozadí miniatury videa.

Vytvořte Worker pro převod textu na obrázek

Po nahrání obrázku vytvořte Worker, který umožní převod textu na obrázek. Tento obrázek lze použít jako překryv na nahraném obrázku pozadí. Použijte rustwasm-worker-template.

Než začnete, budete potřebovat následující:

Vytvořte nový projekt Worker pomocí worker-rust šablonu:

cargo generate https://github.com/cloudflare/rustwasm-worker-template

Nyní provedete několik změn v souborech ve složce projektu.

  1. V lib.rs soubor a přidejte následující blok kódu:
use worker::*;
mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
   // Optionally, get more helpful error messages written to the console in the case of a panic.
   utils::set_panic_hook();

   let router = Router::new();
   router
       .get("/", |_, _| Response::ok("Hello from Workers!"))
       .run(req, env)
       .await
}
  1. Aktualizujte Cargo.toml soubor v worker-to-text adresáři projektu, aby se použil text-to-png, balíček Rust pro vykreslování textu do PNG. Balíček přidejte jako závislost spuštěním:
cargo add [email protected]
  1. Importujte text_to_png knihovnu do vašeho worker-to-text projektu lib.rs .
use text_to_png::{TextPng, TextRenderer};
use worker::*;
mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
   // Optionally, get more helpful error messages written to the console in the case of a panic.
   utils::set_panic_hook();

   let router = Router::new();
   router
       .get("/", |_, _| Response::ok("Hello from Workers!"))
       .run(req, env)
       .await
}
  1. Aktualizujte lib.rs pro vytvoření handle-slash funkce, která aktivuje transformaci obrázku na základě textu předaného do adresy URL jako parametr dotazu.
use text_to_png::{TextPng, TextRenderer};
use worker::*;
mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
   // Optionally, get more helpful error messages written to the console in the case of a panic.
   utils::set_panic_hook();

   let router = Router::new();
   router
       .get("/", |_, _| Response::ok("Hello from Workers!"))
       .run(req, env)
       .await
}

async fn handle_slash(text: String) -> Result<Response> {}
  1. V handle-slash funkci zavolejte TextRenderer jeho přiřazením k hodnotě rendereru, čímž určíte, že chcete použít vlastní písmo. Poté použijte render_text_to_png_data metoda pro převod textu do formátu obrázku. V tomto příkladu vlastní písmo (Inter-Bold.ttf) se nachází v /assets složku v kořenovém adresáři projektu, která se použije pro generování náhledu. Tuto část kódu musíte upravit tak, aby odkazovala na váš vlastní soubor s písmem.
use text_to_png::{TextPng, TextRenderer};
use worker::*;
mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
   // Optionally, get more helpful error messages written to the console in the case of a panic.
   utils::set_panic_hook();

   let router = Router::new();
   router
       .get("/", |_, _| Response::ok("Hello from Workers!"))
       .run(req, env)
       .await
}

async fn handle_slash(text: String) -> Result<Response> {
  let renderer = TextRenderer::try_new_with_ttf_font_data(include_bytes!("../assets/Inter-Bold.ttf"))
    .expect("Example font is definitely loadable");

  let text_png: TextPng = renderer.render_text_to_png_data(text.replace("+", " "), 60, "003682").unwrap();
}
  1. Přepište Router funkci k volání handle_slash když je v URL předán dotaz, jinak vrátit "Hello Worker!" jako odpověď.
use text_to_png::{TextPng, TextRenderer};
use worker::*;
mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
   // Optionally, get more helpful error messages written to the console in the case of a panic.
   utils::set_panic_hook();

  let router = Router::new();
    router
      .get_async("/", |req, _| async move {
        if let Some(text) = req.url()?.query() {
          handle_slash(text.into()).await
        } else {
          handle_slash("Hello Worker!".into()).await
        }
      })
      .run(req, env)
        .await
}

async fn handle_slash(text: String) -> Result<Response> {
  let renderer = TextRenderer::try_new_with_ttf_font_data(include_bytes!("../assets/Inter-Bold.ttf"))
    .expect("Example font is definitely loadable");

  let text_png: TextPng = renderer.render_text_to_png_data(text.replace("+", " "), 60, "003682").unwrap();
}
  1. Ve vašem lib.rs soubor, nastavte hlavičky na content-type: image/png aby se odpověď správně vykreslila jako obrázek PNG.
use text_to_png::{TextPng, TextRenderer};
use worker::*;
mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
   // Optionally, get more helpful error messages written to the console in the case of a panic.
   utils::set_panic_hook();

   let router = Router::new();
    router
      .get_async("/", |req, _| async move {
        if let Some(text) = req.url()?.query() {
          handle_slash(text.into()).await
        } else {
          handle_slash("Hello Worker!".into()).await
        }
      })
      .run(req, env)
        .await
}

async fn handle_slash(text: String) -> Result<Response> {
  let renderer = TextRenderer::try_new_with_ttf_font_data(include_bytes!("../assets/Inter-Bold.ttf"))
    .expect("Example font is definitely loadable");

  let text_png: TextPng = renderer.render_text_to_png_data(text.replace("+", " "), 60, "003682").unwrap();

  let mut headers = Headers::new();
  headers.set("content-type", "image/png")?;

  Ok(Response::from_bytes(text_png.data)?.with_headers(headers))
}

Poslední lib.rs soubor by měl vypadat takto. Celý kód najdete jako ukázkový repozitář na GitHub.

use text_to_png::{TextPng, TextRenderer};
use worker::*;

mod utils;

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
    // Optionally, get more helpful error messages written to the console in the case of a panic.
    utils::set_panic_hook();

    let router = Router::new();

    router
        .get_async("/", |req, _| async move {
            if let Some(text) = req.url()?.query() {
                handle_slash(text.into()).await
            } else {
                handle_slash("Hello Worker!".into()).await
            }
        })
        .run(req, env)
        .await
}

async fn handle_slash(text: String) -> Result<Response> {
    let renderer = TextRenderer::try_new_with_ttf_font_data(include_bytes!("../assets/Inter-Bold.ttf"))
    .expect("Example font is definitely loadable");

    let text = if text.len() > 128 {
        "Nope".into()
    } else {
        text
    };

    let text = urlencoding::decode(&text).map_err(|_| worker::Error::BadEncoding)?;

    let text_png: TextPng = renderer.render_text_to_png_data(text.replace("+", " "), 60, "003682").unwrap();

    let mut headers = Headers::new();
    headers.set("content-type", "image/png")?;

    Ok(Response::from_bytes(text_png.data)?.with_headers(headers))
}

Jakmile dokončíte úpravy projektu, spusťte lokální server pro vývoj Workeru pomocí:

npx wrangler dev

Toto by mělo spustit localhost instance se zobrazeným obrázkem:

Spuštěním wrangler dev spustíte místní server pro svůj Worker

Po přidání parametru dotazu s vlastním textem byste měli obdržet:

Podle výše uvedených pokynů získáte výstupní obrázek

Chcete-li nasadit svůj Worker, otevřete soubor Wrangler a upravte name klíč názvem svého projektu. Níže je uveden příklad s názvem projektu použitým v tomto tutoriálu:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "worker-to-text"
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "worker-to-text"

Poté spusťte npx wrangler deploy příkaz pro nasazení Workeru.

npx wrangler deploy

A .workers.dev doména se pro váš Worker vygeneruje po spuštění wrangler deploy. Tuto doménu použijete v hlavním náhledovém obrázku.

Vytvořte Worker, který zobrazí původní obrázek

Vytvořte Worker, který bude obsluhovat obrázek nahraný do Images, spuštěním:

npm create cloudflare@latest -- thumbnail-image

Při nastavení vyberte následující možnosti:

Chcete-li začít vyvíjet svůj Worker, cd do adresáře nového projektu:

cd thumbnail-image

Tímto se vytvoří nový projekt Worker s názvem thumbnail-image. V src/index.js soubor a přidejte následující blok kódu:

export default {
	async fetch(request, env) {
		const url = new URL(request.url);
		if (url.pathname === "/original-image") {
			const image = await fetch(
				`https://imagedelivery.net/${env.CLOUDFLARE_ACCOUNT_HASH}/${IMAGE_ID}/public`,
			);
			return image;
		}
		return new Response("Image Resizing with a Worker");
	},
};

Aktualizujte env.CLOUDFLARE_ACCOUNT_HASH s vaším ID účtu Cloudflare. Upravte env.IMAGE_ID s vaším ID image.

Spusťte svůj Worker a přejděte na /original-image trasu pro kontrolu vašeho obrázku.

Přidejte na svůj obrázek vlastní text

Nyní použijete transformace obrázků Cloudflare, s fetch metoda, pomocí které přidáte dynamický textový obrázek jako překrytí na obrázek na pozadí. Nejprve zobrazte výsledný obrázek na jiné trase. Novou trasu nazvěte /thumbnail.

export default {
	async fetch(request, env) {
		const url = new URL(request.url);
		if (url.pathname === "/original-image") {
			const image = await fetch(
				`https://imagedelivery.net/${env.CLOUDFLARE_ACCOUNT_HASH}/${IMAGE_ID}/public`,
			);
			return image;
		}

		if (url.pathname === "/thumbnail") {
		}

		return new Response("Image Resizing with a Worker");
	},
};

Dále použijte fetch metoda pro aplikování změn transformace obrázku na pozadí obrázku. Možnosti překrytí (overlay) jsou vnořené v options.cf.image.

export default {
	async fetch(request, env) {
		const url = new URL(request.url);

		if (url.pathname === "/original-image") {
			const image = await fetch(
				`https://imagedelivery.net/${env.CLOUDFLARE_ACCOUNT_HASH}/${IMAGE_ID}/public`,
			);
			return image;
		}

		if (url.pathname === "/thumbnail") {
			fetch(imageURL, {
				cf: {
					image: {},
				},
			});
		}

		return new Response("Image Resizing with a Worker");
	},
};

imageURL je URL obrázku, který chcete použít jako obrázek na pozadí. V cf.image objekt zadejte možnosti, které chcete použít pro obrázek na pozadí.

Přidejte obrázek na pozadí do adresáře assets na GitHubu a odešlete změny na GitHub. URL adresu nahraného obrázku zkopírujte kliknutím levým tlačítkem na obrázek a výběrem Kopírovat URL vzdáleného souboru možnost.

Nahraďte imageURL hodnota se zkopírovanou vzdálenou URL.

if (url.pathname === "/thumbnail") {
	const imageURL =
		"https://github.com/lauragift21/social-image-demo/blob/1ed9044463b891561b7438ecdecbdd9da48cdb03/assets/cover.png?raw=true";
	fetch(imageURL, {
		cf: {
			image: {},
		},
	});
}

Dále přidejte možnosti překrytí do objektu image. Změňte velikost obrázku na požadovanou šířku a výšku pro miniatury YouTube a použijte nakreslit možnost pro přidání překryvného textu pomocí nasazené URL adresy vašeho text-to-image Worker.

fetch(imageURL, {
	cf: {
		image: {
			width: 1280,
			height: 720,
			draw: [
				{
					url: "https://text-to-image.examples.workers.dev",
					left: 40,
				},
			],
		},
	},
});

Transformace obrázků lze testovat až po nasazení Workeru.

Chcete-li nasadit svůj Worker, otevřete soubor Wrangler a upravte name klíč názvem svého projektu. Níže je uveden příklad s názvem projektu použitým v tomto tutoriálu:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "thumbnail-image"
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "thumbnail-image"

Nasaďte svůj Worker spuštěním:

npx wrangler deploy

Příkaz nasadí váš Worker na vlastní workers.dev subdoména. Přejděte do vašeho .workers.dev subdoména a přejděte do /thumbnail trasa.

Měli byste vidět obrázek se změněnou velikostí a textem Hello Workers!.

Podle výše uvedených kroků vygenerujte obrázek se změněnou velikostí.

Nyní text uděláte dynamickým. Díky dynamickému textu jej budete moci měnit a obrázek se automaticky aktualizuje.

Chcete-li přidat dynamický text, připojte libovolný text k /thumbnail URL pomocí parametrů dotazu (query parameters) a předejte ji text-to-image URL Workeru jako parametr.

for (const title of url.searchParams.values()) {
	try {
		const editedImage = await fetch(imageURL, {
			cf: {
				image: {
					width: 1280,
					height: 720,
					draw: [
						{
							url: `https://text-to-image.examples.workers.dev/?${title}`,
							left: 50,
						},
					],
				},
			},
		});
		return editedImage;
	} catch (error) {
		console.log(error);
	}
}

Dokončením tohoto tutoriálu jste úspěšně vytvořili vlastní generátor náhledů pro YouTube.

V tomto tutoriálu jste se naučili používat Cloudflare Workers a transformace obrázků Cloudflare k vytváření vlastních miniatur pro YouTube. Více informací o Cloudflare Workers a transformacích obrázků najdete v Změňte velikost obrázku pomocí Workeru.