Improved rendering of memes

This commit is contained in:
Jon Michael Aanes 2018-06-08 16:22:54 +02:00
parent da8edd57ce
commit 88cb4588b8

105
main.lua
View File

@ -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