Improved rendering of memes
This commit is contained in:
parent
da8edd57ce
commit
88cb4588b8
105
main.lua
105
main.lua
|
@ -117,6 +117,30 @@ local function load_random_font ()
|
||||||
return font_name
|
return font_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local DROSTE_EFFECT_TRIGGERS = {
|
||||||
|
['induktion'] = true,
|
||||||
|
['rekursion'] = true,
|
||||||
|
['uendelig rekursion'] = true,
|
||||||
|
['rekursive'] = true,
|
||||||
|
['rekursive funktioner'] = true,
|
||||||
|
['recursion'] = true,
|
||||||
|
['infinite recursion'] = true,
|
||||||
|
['tail recursion'] = true,
|
||||||
|
['recursive'] = true,
|
||||||
|
['recursive function'] = true,
|
||||||
|
['induktion'] = true,
|
||||||
|
['droste'] = true,
|
||||||
|
['drostle'] = true, -- Misspelling
|
||||||
|
|
||||||
|
['uendelig'] = true,
|
||||||
|
['uendeligt'] = true,
|
||||||
|
|
||||||
|
['strange loop'] = true,
|
||||||
|
['loop'] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
local DROSTE_ITERATIONS_DEFAULT = 5
|
||||||
|
|
||||||
local function fill_in_topics_information (topics)
|
local function fill_in_topics_information (topics)
|
||||||
assert(type(topics) == 'table')
|
assert(type(topics) == 'table')
|
||||||
--
|
--
|
||||||
|
@ -127,9 +151,9 @@ local function fill_in_topics_information (topics)
|
||||||
assert(type(topic) == 'string')
|
assert(type(topic) == 'string')
|
||||||
|
|
||||||
local url = topic_to_image_url[topic]
|
local url = topic_to_image_url[topic]
|
||||||
print(topic, url)
|
|
||||||
|
|
||||||
if url then new_topics[i] = { topic = topic, type = 'image', url = url }
|
if DROSTE_EFFECT_TRIGGERS[topic] then new_topics[i] = { topic = topic, type = 'droste' }
|
||||||
|
elseif url then new_topics[i] = { topic = topic, type = 'image', url = url }
|
||||||
else new_topics[i] = { topic = topic, type = 'text', text = topic }
|
else new_topics[i] = { topic = topic, type = 'text', text = topic }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -162,6 +186,8 @@ local function paste_topic_onto_image (target, topic, x, y, w, h, bg_color, font
|
||||||
elseif topic.type == 'text' then
|
elseif topic.type == 'text' then
|
||||||
local text = topic.text
|
local text = topic.text
|
||||||
draw_centered_text_in_box(font_name, target, text, x, y, w, h, bg_color)
|
draw_centered_text_in_box(font_name, target, text, x, y, w, h, bg_color)
|
||||||
|
elseif topic.type == 'droste' then
|
||||||
|
target:fill_rectangle(x, y, w, h, COLOR_WHITE)
|
||||||
else
|
else
|
||||||
assert(false, topic.type)
|
assert(false, topic.type)
|
||||||
end
|
end
|
||||||
|
@ -185,6 +211,34 @@ local function save_to_cloud (img)
|
||||||
return CONFIG.STORAGE_DIR_URL..img_name
|
return CONFIG.STORAGE_DIR_URL..img_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function draw_droste_effect (target_image, droste_positions, iterations)
|
||||||
|
iterations = interations or DROSTE_ITERATIONS_DEFAULT
|
||||||
|
if #droste_positions <= 0 or iterations <= 0 then return target_image end
|
||||||
|
for _ = 1, iterations do
|
||||||
|
for _, position in ipairs(droste_positions) do
|
||||||
|
local paste_image = target_image:clone()
|
||||||
|
paste_image:crop_and_scale(0, 0, paste_image:get_width(), paste_image:get_height(), position.w, position.h)
|
||||||
|
flatten_onto (target_image, paste_image, position.x, position.y)
|
||||||
|
paste_image:free()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return target_image
|
||||||
|
end
|
||||||
|
|
||||||
|
local function droste_positions_from_topics (topics, places)
|
||||||
|
local droste_poss = {}
|
||||||
|
for i, topic in ipairs(topics) do
|
||||||
|
if topic.type == 'droste' then
|
||||||
|
droste_poss[#droste_poss+1] = {
|
||||||
|
x = places[i].x, y = places[i].y,
|
||||||
|
w = places[i].w, h = places[i].h,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return droste_poss
|
||||||
|
end
|
||||||
|
|
||||||
local function generate_distracted_boyfriend (topics)
|
local function generate_distracted_boyfriend (topics)
|
||||||
assert(type(topics) == 'table' and #topics == 2)
|
assert(type(topics) == 'table' and #topics == 2)
|
||||||
|
|
||||||
|
@ -194,32 +248,57 @@ local function generate_distracted_boyfriend (topics)
|
||||||
|
|
||||||
local HEAD_W, HEAD_H = 150, 150
|
local HEAD_W, HEAD_H = 150, 150
|
||||||
|
|
||||||
local x1, y1 = 640 + math.random(-20, 20), 50 + math.random(-20, 20)
|
local DISTRACTED_BOYFRIEND_POS = {
|
||||||
local x2, y2 = 180 + math.random(-20, 20), 50 + math.random(-20, 20)
|
{ x = 640 + math.random(-20, 20), y = 50 + math.random(-20, 20), w = HEAD_W, h = HEAD_H },
|
||||||
paste_topic_onto_image(base_img, topics[1], x1, y1, HEAD_W, HEAD_H, nil, font_name)
|
{ x = 180 + math.random(-20, 20), y = 50 + math.random(-20, 20), w = HEAD_W, h = HEAD_H },
|
||||||
paste_topic_onto_image(base_img, topics[2], x2, y2, HEAD_W, HEAD_H, nil, font_name)
|
}
|
||||||
|
|
||||||
|
-- Paste topic onto head
|
||||||
|
for index, pos in ipairs(DISTRACTED_BOYFRIEND_POS) do
|
||||||
|
paste_topic_onto_image(base_img, topics[index], pos.x, pos.y, pos.w, pos.h, nil, font_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Droste
|
||||||
|
base_img = draw_droste_effect(base_img, droste_positions_from_topics(topics, DISTRACTED_BOYFRIEND_POS))
|
||||||
|
|
||||||
--
|
--
|
||||||
return save_to_cloud(base_img)
|
return save_to_cloud(base_img)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local BRAIN_ROW_HEIGHT = 150
|
||||||
|
local BRAIN_ROW_WIDTH = 200
|
||||||
|
|
||||||
|
local BRAIN_MAX_EXPLOSION_TOPICS = 6
|
||||||
|
local BRAIN_DROSTE_POS = {}
|
||||||
|
for i = 1, BRAIN_MAX_EXPLOSION_TOPICS do
|
||||||
|
BRAIN_DROSTE_POS[i] = {
|
||||||
|
x = 0,
|
||||||
|
y = (i-1) * BRAIN_ROW_HEIGHT,
|
||||||
|
w = BRAIN_ROW_WIDTH,
|
||||||
|
h = BRAIN_ROW_HEIGHT
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function generate_brain_explosion_image (topics)
|
local function generate_brain_explosion_image (topics)
|
||||||
assert(type(topics) == 'table' and 1 <= #topics and #topics <= 6)
|
assert(type(topics) == 'table' and 1 <= #topics and #topics <= BRAIN_MAX_EXPLOSION_TOPICS)
|
||||||
--
|
--
|
||||||
local ROW_HEIGHT = 150
|
local base_img = imlib.image.new(BRAIN_ROW_WIDTH * 2, BRAIN_ROW_HEIGHT * #topics)
|
||||||
local ROW_WIDTH = 200
|
|
||||||
local base_img = imlib.image.new(ROW_WIDTH * 2, ROW_HEIGHT * #topics)
|
|
||||||
local font_name = choose_random_font()
|
local font_name = choose_random_font()
|
||||||
--
|
--
|
||||||
for i, topic_info in ipairs(topics) do
|
for i, topic_info in ipairs(topics) do
|
||||||
paste_topic_onto_image(base_img, topic_info, 0, (i-1) * ROW_HEIGHT, ROW_WIDTH, ROW_HEIGHT, COLOR_WHITE, font_name)
|
paste_topic_onto_image(base_img, topic_info, 0, (i-1) * BRAIN_ROW_HEIGHT, BRAIN_ROW_WIDTH, BRAIN_ROW_HEIGHT, COLOR_WHITE, font_name)
|
||||||
|
|
||||||
local brain_img = imlib.image.load(CONFIG.IMGGEN_PATH_BRAINS..'brain_'..i..'.png')
|
local brain_img = imlib.image.load(CONFIG.IMGGEN_PATH_BRAINS..'brain_'..i..'.png')
|
||||||
brain_img:crop_and_scale(0, 0, brain_img:get_width(), brain_img:get_height(), ROW_WIDTH, ROW_HEIGHT)
|
brain_img:crop_and_scale(0, 0, brain_img:get_width(), brain_img:get_height(), BRAIN_ROW_WIDTH, BRAIN_ROW_HEIGHT)
|
||||||
flatten_onto (base_img, brain_img, ROW_WIDTH, (i-1) * ROW_HEIGHT)
|
flatten_onto (base_img, brain_img, BRAIN_ROW_WIDTH, (i-1) * BRAIN_ROW_HEIGHT)
|
||||||
brain_img:free()
|
brain_img:free()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Droste
|
||||||
|
base_img = draw_droste_effect(base_img, droste_positions_from_topics(topics, BRAIN_DROSTE_POS))
|
||||||
|
|
||||||
|
-- Save
|
||||||
return save_to_cloud(base_img)
|
return save_to_cloud(base_img)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user