feat: post image diversity — style rotation + random scene/concept + expanded AI concepts bank

This commit is contained in:
Alexey Pavlov
2026-06-15 10:20:22 +03:00
parent 525870c709
commit bede92a520
+21 -12
View File
@@ -63,9 +63,11 @@ const IMAGE_PALETTES = {
* Генерирует картинку к посту через GPT-5 /v1/responses + image_generation. * Генерирует картинку к посту через GPT-5 /v1/responses + image_generation.
*/ */
async function generatePostImage({ post, channel, style = {} }) { async function generatePostImage({ post, channel, style = {} }) {
// Если задано несколько стилей через запятую — случайно выбираем один // Если задано несколько стилей через запятую — случайно выбираем один.
const styleList = (style.image_style || 'flat-illustration') // Если стиль не задан или 'auto' — ротация из трёх редакторских стилей.
.split(',').map(s => s.trim()).filter(s => s && s !== 'auto'); const DEFAULT_ROTATION = 'realistic-photo,3d-render,flat-illustration';
const rawStyle = style.image_style && style.image_style !== 'auto' ? style.image_style : DEFAULT_ROTATION;
const styleList = rawStyle.split(',').map(s => s.trim()).filter(Boolean);
const pickedStyle = styleList[Math.floor(Math.random() * styleList.length)] || 'flat-illustration'; const pickedStyle = styleList[Math.floor(Math.random() * styleList.length)] || 'flat-illustration';
const imageStyle = IMAGE_STYLES[pickedStyle] || IMAGE_STYLES['flat-illustration']; const imageStyle = IMAGE_STYLES[pickedStyle] || IMAGE_STYLES['flat-illustration'];
const palette = style.image_custom_colors const palette = style.image_custom_colors
@@ -78,10 +80,7 @@ async function generatePostImage({ post, channel, style = {} }) {
// Визуальная метафора — конкретный предмет/сцена на основе темы // Визуальная метафора — конкретный предмет/сцена на основе темы
const visualConcept = getPostVisualConcept(post, channel); const visualConcept = getPostVisualConcept(post, channel);
// Антураж + свет — меняется по хешу поста (детерминированно, но разнообразно) // Антураж + свет — случайный выбор при каждой генерации (намеренно, не детерминированно)
let seed = 0;
for (let i = 0; i < post.length && i < 100; i++) seed = (seed * 31 + post.charCodeAt(i)) >>> 0;
const SCENES = [ const SCENES = [
{ setting: 'warm oak desktop surface, afternoon sunlight from left window', lighting: 'golden hour soft shadows', temp: 'warm amber' }, { setting: 'warm oak desktop surface, afternoon sunlight from left window', lighting: 'golden hour soft shadows', temp: 'warm amber' },
{ setting: 'white marble surface, clean studio', lighting: 'flat professional studio', temp: 'cool whites' }, { setting: 'white marble surface, clean studio', lighting: 'flat professional studio', temp: 'cool whites' },
@@ -91,8 +90,11 @@ async function generatePostImage({ post, channel, style = {} }) {
{ setting: 'glass surface over city lights at night', lighting: 'city glow from below', temp: 'multicolor bokeh' }, { setting: 'glass surface over city lights at night', lighting: 'city glow from below', temp: 'multicolor bokeh' },
{ setting: 'antique library floor, surrounded by books, candlelight', lighting: 'warm candlelight side', temp: 'amber parchment' }, { setting: 'antique library floor, surrounded by books, candlelight', lighting: 'warm candlelight side', temp: 'amber parchment' },
{ setting: 'frosted glass, winter morning, ice crystals at edges', lighting: 'diffused winter morning', temp: 'icy blues whites' }, { setting: 'frosted glass, winter morning, ice crystals at edges', lighting: 'diffused winter morning', temp: 'icy blues whites' },
{ setting: 'concrete urban rooftop at golden hour, city skyline behind', lighting: 'backlit warm haze', temp: 'golden urban' },
{ setting: 'minimalist white shelf, single object lit from above', lighting: 'clean overhead spotlight', temp: 'pure whites' },
{ setting: 'old wooden table in a sunlit greenhouse, plants around', lighting: 'dappled greenhouse light', temp: 'fresh greens warm' },
]; ];
const scene = SCENES[seed % SCENES.length]; const scene = SCENES[Math.floor(Math.random() * SCENES.length)];
const prompt = `Generate a 16:9 editorial illustration for a social media post. const prompt = `Generate a 16:9 editorial illustration for a social media post.
@@ -173,10 +175,7 @@ function getPostVisualConcept(post, channel) {
const niche = (channel?.niche || '').toLowerCase(); const niche = (channel?.niche || '').toLowerCase();
const combined = t + ' ' + niche; const combined = t + ' ' + niche;
// Хеш для выбора внутри категории function pick(arr) { return arr[Math.floor(Math.random() * arr.length)]; }
let seed = 0;
for (let i = 0; i < post.length && i < 80; i++) seed = (seed * 31 + post.charCodeAt(i)) >>> 0;
function pick(arr) { return arr[seed % arr.length]; }
const patterns = [ const patterns = [
{ {
@@ -188,6 +187,16 @@ function getPostVisualConcept(post, channel) {
'A master key held up to warm light, intricate cuts visible, golden bokeh background', 'A master key held up to warm light, intricate cuts visible, golden bokeh background',
'A book opening by itself, pages turning rapidly, text rearranging mid-air in warm library', 'A book opening by itself, pages turning rapidly, text rearranging mid-air in warm library',
'An optical prism splitting white light into full spectrum, mounted on dark velvet surface', 'An optical prism splitting white light into full spectrum, mounted on dark velvet surface',
'A chess board mid-game, one piece hovering in the air about to move, dramatic side light',
'An hourglass frozen mid-flow, sand suspended in air, dark moody background',
'A single neuron with glowing dendrites branching outward, macro medical illustration style',
'A telescope pointed at a star map, constellation lines drawn in light, observatory dome open',
'A maze viewed from above, a single glowing path found through it, aerial minimalist',
'A blank canvas with a single brushstroke that transforms into a landscape, studio light',
'Two puzzle pieces clicking together mid-air, warm backlight, close-up macro',
'A vintage radio with dials, sound waves visible as light trails, dark wood surface',
'An open toolbox with glowing tools arranged precisely, overhead industrial light',
'A library ladder reaching impossibly high shelves disappearing into mist, warm amber',
], ],
}, },
{ {