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.
*/
async function generatePostImage({ post, channel, style = {} }) {
// Если задано несколько стилей через запятую — случайно выбираем один
const styleList = (style.image_style || 'flat-illustration')
.split(',').map(s => s.trim()).filter(s => s && s !== 'auto');
// Если задано несколько стилей через запятую — случайно выбираем один.
// Если стиль не задан или '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 imageStyle = IMAGE_STYLES[pickedStyle] || IMAGE_STYLES['flat-illustration'];
const palette = style.image_custom_colors
@@ -78,10 +80,7 @@ async function generatePostImage({ post, channel, style = {} }) {
// Визуальная метафора — конкретный предмет/сцена на основе темы
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 = [
{ 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' },
@@ -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: '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: '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.
@@ -173,10 +175,7 @@ function getPostVisualConcept(post, channel) {
const niche = (channel?.niche || '').toLowerCase();
const combined = t + ' ' + niche;
// Хеш для выбора внутри категории
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]; }
function pick(arr) { return arr[Math.floor(Math.random() * arr.length)]; }
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 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',
'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',
],
},
{