


Sebulan yang lalu, saya mula bekerjasama dalam projek tentang kandungan yang dijana AI untuk pelanggan yang memfokuskan pada sektor teknologi. Peranan saya kebanyakannya tertumpu pada menyediakan SSG menggunakan WordPress sebagai CMS Tanpa Kepala untuk Nuxt Front-end.
Pelanggan pernah menulis artikel beberapa kali seminggu tentang aliran atau situasi berbeza yang mempengaruhi sektor tersebut, dengan harapan dapat meningkatkan trafik ke tapak dan pengeluaran artikelnya, dia memutuskan untuk menggunakan AI untuk menjana artikel untuknya.
Selepas beberapa lama, dengan gesaan yang betul, pelanggan mempunyai cebisan maklumat yang hampir dengan padanan tepat artikel tulisan manusia, adalah sangat sukar untuk mengesan bahawa ia adalah buatan mesin.
Ada kalanya selepas saya beralih menggunakan ciri yang berbeza, saya akan terus ditanya satu perkara khusus.
Eh, bolehkah anda mengemas kini imej yang ditampilkan untuk artikel ini?
Selepas 2 minggu mengemas kini Siaran setiap hari, saya mengalami detik eureka yang kecil.
Mengapa saya tidak mengautomasikan penjanaan imej yang ditampilkan untuk artikel ini menggunakan Kecerdasan Buatan?
Kami sudah mengautomasikan penulisan siaran, mengapa tidak mengautomasikan imej yang ditampilkan?
Pada masa lapang saya, saya sedang bereksperimen dengan LLM generatif pada komputer saya jadi saya mempunyai idea yang kukuh tentang lebih kurang cara menangani usaha sampingan ini. Saya menghantar mesej kepada pelanggan yang memperincikan masalahnya, apa yang saya mahu lakukan dan apa yang akan menjadi kelebihan dan tanpa perlu meyakinkan, saya mendapat lampu hijau untuk mengusahakan ciri ini dan segera saya pergi dengan langkah pertama saya.
1. Seni bina bagaimana penyelesaian akan kelihatan.
Memandangkan saya mempunyai sedikit pendedahan untuk menjalankan model secara tempatan, saya tahu dengan serta-merta adalah tidak mungkin untuk mengehoskan sendiri model tersebut. Dengan dibuang itu saya mula bermain-main dengan API yang menghasilkan imej berdasarkan gesaan teks.
Imej yang ditampilkan terdiri daripada 2 bahagian: grafik terdiri utama dan slogan yang menarik.
Grafik yang digubah ialah beberapa elemen yang berkaitan dengan artikel, disusun dengan cara yang baik dengan kemudian beberapa warna dan tekstur dengan beberapa mod campuran digunakan untuk mencapai beberapa kesan mewah berikutan penjenamaan.
Tagline pendek, 8-12 patah perkataan ayat dengan bayang-bayang yang ringkas di bawahnya.
Berdasarkan ujian saya, saya menyedari bahawa mengikuti laluan AI untuk penjanaan imej tidak praktikal. Kualiti imej tidak memenuhi jangkaan, dan proses itu terlalu memakan masa untuk membenarkan penggunaannya. Memandangkan ini akan dijalankan sebagai fungsi AWS Lambda, di mana masa pelaksanaan secara langsung memberi kesan kepada kos.
Dengan itu dibuang, saya menggunakan Pelan B: menumbuk imej dan aset reka bentuk bersama-sama menggunakan API Kanvas JavaScript.
Melihat secara mendalam, kami mempunyai terutamanya 5 gaya siaran ringkas, dan sekitar 4 jenis tekstur dan 3 daripadanya menggunakan penjajaran, gaya dan kedudukan teks yang sama. Selepas membuat beberapa matematik saya fikir:
Hmm, Jika saya mengambil 3 imej ini, ambil 8 tekstur dan bermain dengan mod campuran, saya boleh mendapatkan sekitar post 24 variasi
Memandangkan 3 jenis siaran tersebut mempunyai gaya teks yang sama, ia boleh dikatakan satu templat.
Dengan penyelesaian itu, saya berpindah ke Penjana Tagline. Saya ingin mencipta slogan berdasarkan kandungan dan tajuk artikel. Saya memutuskan untuk menggunakan API ChatGPT memandangkan syarikat sudah membayar untuknya dan selepas beberapa percubaan dan pengubahsuaian gesaan, saya mempunyai MVP yang sangat baik untuk penjana slogan saya.
Dengan 2 bahagian tugasan yang paling sukar diselesaikan, saya meluangkan sedikit masa di Figma menyusun rajah untuk seni bina akhir perkhidmatan saya.
2. Mengekodkan lambda saya
Rancangannya adalah untuk mencipta fungsi Lambda yang mampu menganalisis kandungan siaran, menjana slogan dan memasang imej yang ditampilkan—semuanya disepadukan dengan lancar dengan WordPress.
Saya akan memberikan beberapa kod tetapi cukup untuk menyampaikan idea keseluruhan kepada ke.
Menganalisis kandungan
Fungsi Lambda bermula dengan mengekstrak parameter yang diperlukan daripada muatan acara masuk:
const { title: request_title, content, backend, app_password} = JSON.parse(event.body);
- tajuk dan kandungan: Ini menyediakan konteks artikel.
- belakang: URL belakang WordPress untuk muat naik imej.
- app_password: Token pengesahan yang akan saya gunakan untuk memuat naik sebagai pengguna saya menggunakan Wordpress Rest API.
Menjana Tagline
Tugas utama pertama fungsi ini ialah menjana slogan menggunakan fungsi analyzeContent, yang menggunakan API OpenAI untuk mencipta slogan yang layak klik berdasarkan tajuk dan kandungan artikel.
Fungsi kami mengambil tajuk dan kandungan siaran tetapi mengembalikan slogan, sentimen siaran untuk mengetahui sama ada siaran adalah pendapat yang positif, negatif atau neutral dan simbol syarikat pilihan daripada syarikat indeks S&P.
const { slogan, sentimen, syarikat } = menunggu analisisKandungan({ tajuk: request_title, kandungan });
Langkah ini adalah kritikal, kerana slogan secara langsung mempengaruhi estetika imej.
Mencipta Imej Pilihan
Seterusnya, fungsi generateImage bermula:
let buffer; buffer = await generateImage({ title: tagline, company_logo: company_logo, sentiment: sentiment, });
Fungsi ini mengendalikan:
- Mereka bentuk gubahan.
- Melapisi tekstur, warna dan elemen penjenamaan.
- Menggunakan kesan dan mencipta tajuk.
Berikut ialah pecahan langkah demi langkah tentang cara ia berfungsi:
Fungsi generateImage bermula dengan menyediakan kanvas kosong, menentukan dimensinya dan menyediakannya untuk mengendalikan semua elemen reka bentuk.
let buffer; buffer = await generateImage({ title: tagline, company_logo: company_logo, sentiment: sentiment, });
Dari situ, imej latar belakang rawak dimuatkan daripada koleksi aset yang telah ditetapkan. Imej ini disusun mengikut penjenamaan berorientasikan teknologi sambil membenarkan kepelbagaian yang mencukupi merentas siaran. Imej latar belakang dipilih secara rawak berdasarkan sentimennya.
Untuk memastikan setiap imej latar belakang kelihatan hebat, saya mengira dimensinya secara dinamik berdasarkan nisbah bidang. Ini mengelakkan herotan sambil mengekalkan keseimbangan visual.
Menambah Tagline
Slogan itu pendek tetapi berdasarkan beberapa peraturan, ayat yang memberi impak ini dibahagikan kepada bahagian yang boleh diurus dan digayakan secara dinamik untuk memastikan ia sentiasa boleh dibaca, tanpa mengira panjang atau saiz kanvas berdasarkan bilangan perkataan untuk baris, panjang perkataan, dsb. .
const COLOURS = { BLUE: "#33b8e1", BLACK: "#000000", } const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const images_path = path.join(__dirname, 'images/'); const files_length = fs.readdirSync(images_path).length; const images_folder = process.env.ENVIRONMENT === "local" ? "./images/" : "/var/task/images/"; registerFont("/var/task/fonts/open-sans.bold.ttf", { family: "OpenSansBold" }); registerFont("/var/task/fonts/open-sans.regular.ttf", { family: "OpenSans" }); console.log("1. Created canvas"); const canvas = createCanvas(1118, 806); let image = await loadImage(`${images_folder}/${Math.floor(Math.random() * (files_length - 1 + 1)) + 1}.jpg`); let textBlockHeight = 0; console.log("2. Image loaded"); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const aspectRatio = image.width / image.height; console.log("3. Defined ASPECT RATIO",) let drawWidth, drawHeight; if (image.width > image.height) { // Landscape orientation: fit by width drawWidth = canvasWidth; drawHeight = canvasWidth / aspectRatio; } else { // Portrait orientation: fit by height drawHeight = canvasHeight; drawWidth = canvasHeight * aspectRatio; } // Center the image const x = (canvasWidth - drawWidth) / 2; const y = (canvasHeight - drawHeight) / 2; const ctx = canvas.getContext("2d"); console.log("4. Centered Image") ctx.drawImage(image, x, y, drawWidth, drawHeight);
Akhir sekali, kanvas ditukar menjadi penimbal PNG.
console.log("4.1 Text splitting"); if (splitText.length === 1) { const isItWiderThanHalf = ctx.measureText(splitText[0]).width > ((canvasWidth / 2) + 160); const wordCount = splitText[0].split(" ").length; if (isItWiderThanHalf && wordCount > 4) { const refactored_line = splitText[0].split(" ").reduce((acc, curr, i) => { if (i % 3 === 0) { acc.push([curr]); } else { acc[acc.length - 1].push(curr); } return acc; }, []).map((item) => item.join(" ")); refactored_line[1] = "[s]" + refactored_line[1] + "[s]"; splitText = refactored_line } } let tagline = splitText.filter(item => item !== '' && item !== '[br]' && item !== '[s]' && item !== '[/s]' && item !== '[s]'); let headlineSentences = []; let lineCounter = { total: 0, reduced_line_counter: 0, reduced_lines_indexes: [] } console.log("4.2 Tagline Preparation", tagline); for (let i = 0; i item !== '' && item !== '[s]' && item !== '[/s]'); const lineWidth = ctx.measureText(finalLine[0]).width const halfOfWidth = canvasWidth / 2; if (lineWidth > halfOfWidth && finalLine[0]) { let splitted_text = finalLine[0].split(" ").reduce((acc, curr, i) => { const modulus = finalLine[0].split(" ").length >= 5 ? 3 : 2; if (i % modulus === 0) { acc.push([curr]); } else { acc[acc.length - 1].push(curr); } return acc; }, []); let splitted_text_arr = [] splitted_text.forEach((item, _) => { let lineText = item.join(" "); item = lineText splitted_text_arr.push(item) }) headlineSentences[i] = splitted_text_arr[0] + '/s/' if (splitted_text_arr[1]) { headlineSentences.splice(i + 1, 0, splitted_text_arr[1] + '/s/') } } else { headlineSentences.push("/s/" + finalLine[0] + "/s/") } } else { headlineSentences.push(line) } } console.log("5. Drawing text on canvas", headlineSentences); const headlineSentencesLength = headlineSentences.length; let textHeightAccumulator = 0; for (let i = 0; i item !== '/s/'); const nextLine = headlineSentences[i + 1]; if (nextLine && /^\s*$/.test(nextLine)) { headlineSentences.splice(i + 1, 1); } let line = headlineSentences[i]; if (!line) continue; let lineText = line.trim(); let textY; ctx.font = " 72px OpenSans"; const cleanedUpLine = lineText.includes('/s/') ? lineText.replace(/\s+/g, ' ') : lineText; const lineWidth = ctx.measureText(cleanedUpLine).width const halfOfWidth = canvasWidth / 2; lineCounter.total += 1 const isLineTooLong = lineWidth > (halfOfWidth + 50); if (isLineTooLong) { if (lineText.includes(':')) { const split_line_arr = lineText.split(":") if (split_line_arr.length > 1) { lineText = split_line_arr[0] + ":"; if (split_line_arr[1]) { headlineSentences.splice(i + 1, 0, split_line_arr[1]) } } } ctx.font = "52px OpenSans"; lineCounter.reduced_line_counter += 1 if (i === 0 && headlineSentencesLength === 2) { is2LinesAndPreviewsWasReduced = true } lineCounter.reduced_lines_indexes.push(i) } else { if (i === 0 && headlineSentencesLength === 2) { is2LinesAndPreviewsWasReduced = false } } if (lineText.includes("/s/")) { lineText = lineText.replace(/\/s\//g, ""); if (headlineSentencesLength > (i + 1) && i (canvasWidth / 2.35)) { ctx.font = "84px OpenSansBold"; assignedSize = 80 } else { ctx.font = "84px OpenSansBold"; assignedSize = 84 } } else { if (i === headlineSentencesLength - 1 && lineWidth (canvasWidth / 2) + 120) { if (assignedSize === 84) { ctx.font = "72px OpenSansBold"; } else if (assignedSize === 80) { ctx.font = "64px OpenSansBold"; textHeightAccumulator += 8 } else { ctx.font = "52px OpenSansBold"; } } } else { const textWidth = ctx.measureText(lineText).width if (textWidth > (canvasWidth / 2)) { ctx.font = "44px OpenSans"; textHeightAccumulator += 12 } else if (i === headlineSentencesLength - 1) { textHeightAccumulator += 12 } } ctx.fillStyle = "white"; ctx.textAlign = "center"; const textHeight = ctx.measureText(lineText).emHeightAscent; textHeightAccumulator += textHeight; if (headlineSentencesLength == 3) { textY = (canvasHeight / 3) } else if (headlineSentencesLength == 4) { textY = (canvasHeight / 3.5) } else { textY = 300 } textY += textHeightAccumulator; const words = lineText.split(' '); console.log("words", words, lineText, headlineSentences) const capitalizedWords = words.map(word => { if (word.length > 0) return word[0].toUpperCase() + word.slice(1) return word }); const capitalizedLineText = capitalizedWords.join(' '); ctx.fillText(capitalizedLineText, canvasWidth / 2, textY); }
Akhirnya!!! Memuat naik Imej ke WordPress
Selepas berjaya menjana penimbal imej, fungsi uploadImageToWordpress dipanggil.
Fungsi ini mengendalikan beban berat menghantar imej ke WordPress menggunakan API REST dengan Mengekodkan Imej untuk WordPress.
Fungsi ini menyediakan slogan terlebih dahulu untuk digunakan sebagai nama fail dengan membersihkan ruang dan aksara khas:
const buffer = canvas.toBuffer("image/png"); return buffer;
Penimbal imej kemudiannya ditukar menjadi objek Blob untuk menjadikannya serasi dengan API WordPress:
fail const = new Blob([buffer], { type: "image/png" });
Menyediakan Permintaan API Menggunakan imej dan slogan yang dikodkan, fungsi membina objek FormData dan saya menambah metadata pilihan, seperti alt_text untuk kebolehaksesan dan kapsyen untuk konteks.
const createSlug = (string) => { return string.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); }; const image_name = createSlug(tagline);
Untuk pengesahan, nama pengguna dan kata laluan aplikasi dikodkan dalam Base64 dan disertakan dalam pengepala permintaan:
formData.append("file", file, image_name + ".png"); formData.append("alt_text", `${tagline} image`); formData.append("caption", "Uploaded via API");
Menghantar Imej Permintaan POST dibuat ke titik akhir media WordPress dengan data dan pengepala yang disediakan dan selepas menunggu balasan, saya mengesahkan kejayaan atau kesilapan.
const credentials = `${username}:${app_password}`; const base64Encoded = Buffer.from(credentials).toString("base64");
Jika berjaya, saya mengembalikan respons media yang sama dalam lambda.
Beginilah rupa lambda saya pada akhirnya.
const response = await fetch(`${wordpress_url}wp-json/wp/v2/media`, { method: "POST", headers: { Authorization: "Basic " + base64Encoded, contentType: "multipart/form-data", }, body: formData, }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Error uploading image: ${response.statusText}, Details: ${errorText}`); }
Ini adalah contoh imej yang dihasilkan oleh skrip saya. Ia tidak digunakan dalam pengeluaran, hanya dibuat dengan aset generik untuk contoh ini.
Kesudahannya
Suatu masa telah berlalu dan semua orang gembira kerana kita tidak lagi mempunyai artikel yang tidak bergambar atau kelihatan kosong, bahawa imej adalah padanan yang rapat dengan yang dihasilkan oleh pereka, pereka gembira kerana dia hanya memberi tumpuan kepada mereka bentuk untuk usaha pemasaran lain di seluruh syarikat.
Tetapi masalah baru timbul: kadangkala pelanggan tidak menyukai Imej yang dihasilkan dan dia akan meminta saya memutarkan skrip saya untuk menjana yang baharu untuk siaran tertentu.
Ini membawa saya ke sidequest saya yang seterusnya: Pemalam Wordpress untuk Menjana Imej Pilihan Secara Manual menggunakan Kepintaran Buatan untuk Siaran Khusus
Atas ialah kandungan terperinci AWS JavaScript WordPress = Strategi Automasi Kandungan Seronok Menggunakan Kepintaran Buatan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Penjelasan terperinci mengenai kaedah penggantian rentetan javascript dan Soalan Lazim Artikel ini akan meneroka dua cara untuk menggantikan watak rentetan dalam JavaScript: Kod JavaScript dalaman dan HTML dalaman untuk laman web. Ganti rentetan di dalam kod JavaScript Cara yang paling langsung ialah menggunakan kaedah pengganti (): str = str.replace ("cari", "ganti"); Kaedah ini hanya menggantikan perlawanan pertama. Untuk menggantikan semua perlawanan, gunakan ungkapan biasa dan tambahkan bendera global g: str = str.replace (/fi

Tutorial ini menunjukkan kepada anda bagaimana untuk mengintegrasikan API carian Google tersuai ke dalam blog atau laman web anda, menawarkan pengalaman carian yang lebih halus daripada fungsi carian tema WordPress standard. Ia menghairankan mudah! Anda akan dapat menyekat carian ke y

Jadi di sini anda, bersedia untuk mempelajari semua perkara ini yang dipanggil Ajax. Tetapi, apa sebenarnya? Istilah Ajax merujuk kepada kumpulan teknologi longgar yang digunakan untuk membuat kandungan web yang dinamik dan interaktif. Istilah Ajax, yang asalnya dicipta oleh Jesse J

Siri artikel ini ditulis semula pada pertengahan 2017 dengan maklumat terkini dan contoh segar. Dalam contoh JSON ini, kita akan melihat bagaimana kita dapat menyimpan nilai mudah dalam fail menggunakan format JSON. Menggunakan notasi pasangan nilai utama, kami boleh menyimpan apa-apa jenis

Leverage JQuery untuk Layouts Laman Web yang mudah: 8 Plugin Essential JQuery memudahkan susun atur laman web dengan ketara. Artikel ini menyoroti lapan plugin jQuery yang kuat yang menyelaraskan proses, terutamanya berguna untuk penciptaan laman web manual

Mata teras Ini dalam JavaScript biasanya merujuk kepada objek yang "memiliki" kaedah, tetapi ia bergantung kepada bagaimana fungsi dipanggil. Apabila tidak ada objek semasa, ini merujuk kepada objek global. Dalam penyemak imbas web, ia diwakili oleh tetingkap. Apabila memanggil fungsi, ini mengekalkan objek global; tetapi apabila memanggil pembina objek atau mana -mana kaedahnya, ini merujuk kepada contoh objek. Anda boleh mengubah konteks ini menggunakan kaedah seperti panggilan (), memohon (), dan mengikat (). Kaedah ini memanggil fungsi menggunakan nilai dan parameter yang diberikan. JavaScript adalah bahasa pengaturcaraan yang sangat baik. Beberapa tahun yang lalu, ayat ini

JQuery adalah rangka kerja JavaScript yang hebat. Walau bagaimanapun, seperti mana -mana perpustakaan, kadang -kadang perlu untuk mendapatkan di bawah tudung untuk mengetahui apa yang sedang berlaku. Mungkin kerana anda mengesan bug atau hanya ingin tahu tentang bagaimana jQuery mencapai UI tertentu

Siaran ini menyusun helaian cheat berguna, panduan rujukan, resipi cepat, dan coretan kod untuk perkembangan aplikasi Android, BlackBerry, dan iPhone. Tiada pemaju harus tanpa mereka! Panduan Rujukan Gesture Touch (PDF) Sumber yang berharga untuk desig


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

Dreamweaver Mac版
Alat pembangunan web visual

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa
