מדריך קלאודפלייר בעברית

תיעוד 208

יצירת תמונות ממוזערות ליוטיוב עם Workers ו-Cloudflare Image Resizing

במדריך זה תלמד איך ליצור באופן תכנותי תמונה ממוזערת מותאמת אישית ליוטיוב באמצעות Cloudflare Workers ו-Cloudflare Image Resizing. ייתכן שתרצה ליצור תמונה ממוזערת מותאמת אישית ליוטיוב כדי להתאים את העיצוב של התמונה הממוזערת, את הקריאות לפעולה ואת התמונות שבהן משתמשים, כדי לעודד צופים נוספים לצפות בסרטון שלך.

המדריך הזה יעזור לך להבין איך לעבוד עם Images, עם Image Resizing ועם Cloudflare Workers.

#לפני שמתחילים

כל המדריכים מניחים שכבר השלמת את מדריך תחילת העבודה, שמגדיר לך חשבון Cloudflare Workers, את C3 ↗︎ ואת Wrangler.

כדי לעקוב אחרי המדריך הזה, ודא ש-Node, Cargo ו-Wrangler מותקנים במחשב שלך.

#יעדי למידה

במדריך זה תלמד איך:

  • להעלות תמונות ל-Cloudflare באמצעות לוח הבקרה של Cloudflare או באמצעות ה-API.
  • להגדיר פרויקט Worker עם Wrangler.
  • לעבד תמונות באמצעות המרות תמונה ב-Worker שלך.

#העלאת התמונה שלך

כדי ליצור תמונה ממוזערת מותאמת אישית, תחילה צריך להעלות תמונת רקע ל-Cloudflare Images. היא תשמש כתמונה שעליה תבצע המרות כדי ליצור את התמונות הממוזערות.

Cloudflare Images מאפשר לאחסן, לשנות גודל, לבצע אופטימיזציה ולספק תמונות במהירות ובאופן מאובטח. כדי להתחיל, העלה את התמונות שלך ללוח הבקרה של Cloudflare או השתמש ב-Upload API.

#העלאה באמצעות לוח הבקרה

כדי להעלות תמונה באמצעות לוח הבקרה של Cloudflare:

  1. בלוח הבקרה של Cloudflare, עבור אל הדף Transformations. מעבר אל Transformations ↗
  2. השתמש ב-Quick Upload כדי לגרור ולשחרר תמונה, או לחץ כדי לעיין ולבחור קובץ מהקבצים המקומיים שלך.
  3. אחרי שהתמונה הועלתה, הצג אותה באמצעות כתובת ה-URL שנוצרה.

#העלאה באמצעות ה-API

כדי להעלות את התמונה שלך באמצעות ה-API של Upload via URL, עיין בדוגמה שלהלן:

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'
  • ACCOUNT_ID: מזהה החשבון של המשתמש הנוכחי, שאפשר למצוא בהגדרות החשבון שלך.
  • API_TOKEN: צריך ליצור אותו עם היקף הרשאת Images.
  • PATH_TO_IMAGE: מציין את כתובת ה-URL של התמונה שברצונך להעלות.

לאחר מכן תקבל תשובה דומה לזו:

{
	"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": []
}

עכשיו, אחרי שהעלית את התמונה שלך, תשתמש בה כתמונת הרקע של התמונה הממוזערת של הסרטון שלך.

#יצירת Worker להמרת טקסט לתמונה

אחרי העלאת התמונה, צור Worker שיאפשר לך להמיר טקסט לתמונה. אפשר להשתמש בתמונה הזו כשכבת על מעל תמונת הרקע שהעלית. השתמש ב-rustwasm-worker-template ↗︎.

לפני שתתחיל תצטרך את אלה:

  • גרסה עדכנית של Rust ↗︎.

  • גישה לפקודת המשנה cargo-generate:

    cargo install cargo-generate

צור פרויקט Worker חדש באמצעות התבנית worker-rust:

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

עכשיו תבצע כמה שינויים בקבצים בתיקיית הפרויקט שלך.

  1. בקובץ lib.rs, הוסף את בלוק הקוד הבא:
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. עדכן את הקובץ Cargo.toml בתיקיית הפרויקט worker-to-text כדי להשתמש ב-text-to-png ↗︎, חבילת Rust לעיבוד טקסט ל-PNG. הוסף את החבילה כתלות על ידי הרצה של:
cargo add [email protected]
  1. ייבא את הספרייה text_to_png לקובץ lib.rs של הפרויקט worker-to-text.
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. עדכן את lib.rs כדי ליצור פונקציה handle-slash שתפעיל את המרת התמונה לפי הטקסט שמועבר לכתובת ה-URL כפרמטר שאילתה.
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. בפונקציה handle-slash, קרא ל-TextRenderer על ידי הקצאה שלו לערך renderer, וציין שברצונך להשתמש בגופן מותאם אישית. לאחר מכן, השתמש במתודה render_text_to_png_data כדי להמיר את הטקסט לפורמט תמונה. בדוגמה זו, הגופן המותאם אישית (Inter-Bold.ttf) נמצא בתיקייה /assets בשורש הפרויקט, והוא ישמש ליצירת התמונה הממוזערת. עליך לעדכן את החלק הזה של הקוד כך שיצביע על קובץ הגופן המותאם אישית שלך.
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. כתוב מחדש את הפונקציה Router כך שתקרא ל-handle_slash כאשר מועברת שאילתה בכתובת ה-URL, ואחרת תחזיר את "Hello Worker!" כתשובה.
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. בקובץ lib.rs שלך, הגדר את הכותרות ל-content-type: image/png כדי שהתשובה תוצג נכון כתמונת 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))
}

הקובץ הסופי lib.rs אמור להיראות כך. את הקוד המלא אפשר למצוא כמאגר דוגמה ב-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))
}

אחרי שסיימת לעדכן את הפרויקט, הפעל שרת מקומי לפיתוח ה-Worker שלך על ידי הרצה של:

npx wrangler dev

פעולה זו אמורה להעלות מופע localhost עם התמונה המוצגת:

הרץ את wrangler dev כדי להפעיל שרת מקומי ל-Worker שלך

כאשר מוסיפים פרמטר שאילתה עם טקסט מותאם אישית, אמור להתקבל:

עקוב אחרי ההוראות שלמעלה כדי לקבל תמונת פלט

כדי לפרוס את ה-Worker שלך, פתח את קובץ Wrangler ועדכן את המפתח name בשם הפרויקט שלך. להלן דוגמה עם שם הפרויקט של המדריך הזה:

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

לאחר מכן הרץ את הפקודה npx wrangler deploy כדי לפרוס את ה-Worker שלך.

npx wrangler deploy

דומיין .workers.dev ייווצר עבור ה-Worker שלך אחרי הרצה של wrangler deploy. תשתמש בדומיין הזה בתמונה הממוזערת הראשית.

#יצירת Worker להצגת התמונה המקורית

צור Worker שיגיש את התמונה שהעלית ל-Images על ידי הרצה של אחת מהפקודות הבאות:

npm:

npm create cloudflare@latest -- thumbnail-image

yarn:

yarn create cloudflare thumbnail-image

pnpm:

pnpm create cloudflare@latest thumbnail-image

בהגדרה, בחר את האפשרויות הבאות:

  • עבור What would you like to start with?, בחר Hello World example.
  • עבור Which template would you like to use?, בחר Worker only.
  • עבור Which language do you want to use?, בחר JavaScript.
  • עבור Do you want to use git for version control?, בחר Yes.
  • עבור Do you want to add an AGENTS.md file to help AI coding tools understand Cloudflare APIs?, בחר Yes.
  • עבור Do you want to deploy your application?, בחר No (נבצע כמה שינויים לפני הפריסה).

כדי להתחיל לפתח את ה-Worker שלך, בצע cd לתיקיית הפרויקט החדשה:

cd thumbnail-image

פעולה זו תיצור פרויקט Worker חדש בשם thumbnail-image. בקובץ src/index.js, הוסף את בלוק הקוד הבא:

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");
	},
};

עדכן את env.CLOUDFLARE_ACCOUNT_HASH עם מזהה חשבון Cloudflare שלך. עדכן את env.IMAGE_ID עם מזהה התמונה שלך.

הרץ את ה-Worker שלך ועבור אל הנתיב /original-image כדי לבדוק את התמונה שלך.

#הוספת טקסט מותאם אישית על התמונה

עכשיו תשתמש בהמרות תמונה של Cloudflare, עם המתודה fetch, כדי להוסיף את תמונת הטקסט הדינמית שלך כשכבת על מעל תמונת הרקע. התחל בהצגת התמונה המתקבלת בנתיב אחר. קרא לנתיב החדש /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");
	},
};

בהמשך, השתמש במתודה fetch כדי להחיל את שינויי המרת התמונה מעל תמונת הרקע. אפשרויות שכבת העל מקוננות ב-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 הוא כתובת ה-URL של התמונה שברצונך להשתמש בה כתמונת רקע. באובייקט cf.image, ציין את האפשרויות שברצונך להחיל על תמונת הרקע.

הערה

במועד הפרסום, המרות תמונה של Cloudflare אינן מאפשרות שינוי גודל של תמונות ב-Worker שמאוחסנות ב-Cloudflare Images. במקום להשתמש בתמונה שהגשת בנתיב /original-image, תשתמש באותה תמונה ממקור אחר.

הוסף את תמונת הרקע שלך לספריית assets ב-GitHub ודחוף את השינויים שלך ל-GitHub. העתק את כתובת ה-URL של העלאת התמונה באמצעות לחיצה עם הכפתור השמאלי על התמונה ובחירה באפשרות Copy Remote File Url.

החלף את הערך של imageURL בכתובת ה-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: {},
		},
	});
}

בהמשך, הוסף אפשרויות שכבת על באובייקט התמונה. שנה את גודל התמונה לרוחב ולגובה המועדפים לתמונות ממוזערות של YouTube והשתמש באפשרות draw כדי להוסיף טקסט כשכבת על באמצעות כתובת ה-URL הפרוסה של ה-Worker שלך בשם text-to-image.

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

אפשר לבדוק המרות תמונה רק כשאתה פורס את ה-Worker.

כדי לפרוס את ה-Worker, פתח את קובץ Wrangler שלך ועדכן את המפתח name בשם הפרויקט שלך. להלן דוגמה עם שם הפרויקט של המדריך הזה:

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

פרוס את ה-Worker באמצעות הרצה של:

npx wrangler deploy

הפקודה פורסת את ה-Worker לתת-דומיין workers.dev מותאם אישית. עבור לתת-הדומיין .workers.dev שלך ועבור לנתיב /thumbnail.

אתה אמור לראות את התמונה שגודלה שונה עם הטקסט Hello Workers!.

עקוב אחרי השלבים שלמעלה כדי ליצור את התמונה שגודלה שונה.

עכשיו תהפוך את הטקסט המוחל לדינמי. הפיכת הטקסט שלך לדינמי תאפשר לך לשנות את הטקסט ושהוא יתעדכן בתמונה באופן אוטומטי.

כדי להוסיף טקסט דינמי, צרף כל טקסט שמצורף לכתובת ה-URL של /thumbnail באמצעות פרמטרי שאילתה והעבר אותו לכתובת ה-URL של ה-Worker בשם text-to-image כפרמטר.

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);
	}
}

עם השלמת המדריך הזה, יצרת בהצלחה מחולל תמונות ממוזערות מותאמות אישית ל-YouTube.

#משאבים קשורים

במדריך הזה למדת איך להשתמש ב-Cloudflare Workers ובהמרות תמונה של Cloudflare כדי ליצור תמונות ממוזערות מותאמות אישית ל-YouTube. כדי ללמוד עוד על Cloudflare Workers ועל המרות תמונה, עיין בשינוי גודל של תמונה עם Worker.