superject/cards/deck-neural.rb

236 lines
6.4 KiB
Ruby
Executable file

#!/usr/bin/env ruby -W0
# aprox. running time
# ./deck-neural.rb 144.08s user 10.49s system 28% cpu 8:55.15 total
# ./deck-neural.rb 155.95s user 10.38s system 30% cpu 9:00.29 total
# cards-36.csv
# ./deck-neural.rb 30.74s user 2.63s system 105% cpu 31.507 total
# 50 cards
# ./deck-neural.rb 76.23s user 6.31s system 132% cpu 1:02.50 total
require 'squib'
require 'rest-client'
require 'open-uri'
require 'json'
require 'digest'
require 'mini_magick'
require 'unsplash'
require 'pexels'
# cards from local csv and images vis text2image GAN (or clip art)
#layouts = ['economy.yml', 'space-layout-1.yml']
layouts = ['space-layout-3.yml']
# cards descriptions
#$cards_csv = 'cards-a1.csv' # 16h
#$cards_csv = 'cards-a2.csv' # 17h
$cards_csv = 'cards-a3.csv' # 18h
#$cards_csv = 'cards-test-003.csv'
#$cards_csv = 'cards.csv'
# where to get images? try "t2i" or "unsplash" or "pexels"
$img_source = "t2i"
# https://deepai.org/machine-learning-model/text2img
$deepai_api_key = "59b70a3d-d42a-42be-979d-d09ec08ec7e0"
$pexels_api_key = "563492ad6f917000010000016e741b30a565426c90e5b65b6b34063b"
# prod the GAN or search in a potentially relevant direction with a keyword or phrase prefix
$keyword = ""
# unsplash config
Unsplash.configure do |config|
config.application_access_key = "FWIsA-zAhsj3biPbVH3-H6qoeB30EVazjQpIjlrnaoE"
config.application_secret = "Qcr0ETekpsPVMsGBRSmHSsF7NvAnqWkiZmKw9KP9Ros"
config.application_redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
config.utm_source = "pandemic"
end
# cards descriptions input from csv
if $cards_csv
data = Squib.csv file: $cards_csv
else
raise "no cards file defined"
end
# text2image slurp
def get_img_t2i (phrase)
puts "test2img> #{$keyword} #{phrase}"
d0 = Digest::RMD160.hexdigest phrase
r0 = RestClient::Request.execute(method: :post, url: 'https://api.deepai.org/api/text2img', timeout: 600,
headers: {'api-key' => $deepai_api_key },
payload: { 'text' => "#{$keyword} #{$phrase}" } )
f0 = "img/#{d0}.png"
t0 = MiniMagick::Image.open(JSON.parse(r0)['output_url'])
t0.format('png').write(f0)
puts "wrote: " + f0
return f0
end
# unsplash
# - https://github.com/unsplash/unsplash_rb
# - https://www.rubydoc.info/github/unsplash/unsplash_rb/
def get_img_unsplash (phrase)
puts "unsplash> #{$keyword} #{phrase}"
d0 = Digest::RMD160.hexdigest phrase
r0 = Unsplash::Photo.random(query: "#{$keyword} #{phrase}", orientation: "squarish")
if true
f0 = "img/#{d0}.png"
t0 = MiniMagick::Image.open(r0.urls.regular)
t0.format('png').write(f0)
puts "wrote: " + f0
return f0
else
p "couldn't find an image for #{$keyword} #{phrase}..."
return "img/blank.png"
end
rescue
p "wonk? err..."
return "img/blank.png"
end
# pexels
$pxl = Pexels::Client.new($pexels_api_key)
def get_img_pexels (phrase)
puts "pexels> #{$keyword} #{phrase}"
d0 = Digest::RMD160.hexdigest phrase
r0 = $pxl.photos.search("#{$keyword} #{phrase}", per_page: 1)
f0 = "img/#{d0}.png"
if !r0.photos.empty?
r1 = r0.photos[0].src["portrait"]
t0 = MiniMagick::Image.open(r1)
t0.format('png').write(f0)
p "wrote: " + f0
return f0
else
p "couldn't find an image for #{$keyword} #{phrase}..."
return "img/blank.png"
end
end
# other options for automated image collation
# - https://pixabay.com/api/docs/#api_search_images
# - https://github.com/public-apis/public-apis#photography
# - https://en.wikipedia.org/wiki/Wikipedia:Public_domain_image_resources
# - https://commons.wikimedia.org/wiki/Category:Images
# - https://rapidapi.com/collection/image-apis
# - https://github.com/gztchan/awesome-design#stock
# colourings...
c1 = '#9f68ed'
c2 = '#ed9f68'
c3 = '#b5ed68'
c4 = '#eeeeee'
c1 = '#503143'
c2 = '#9a532b'
c3 = '#c49b60'
c4 = '#79ad9f'
c5 = '#193439'
# Forest Green (#2C5F2D) and Moss Green (#97BC62FF)
c1 = '#d9b929'
c2 = '#d96129'
c3 = '#c3c7d2'
c4 = '#6689a2'
# conditional coloring
# https://squib.readthedocs.io/en/v0.15.0/colors.html?highlight=color#samples
color = c1
bg=[]
fg=[]
Squib::Deck.new cards: data['name'].size, width: '38mm', height: '60mm', layout: layouts do
# set background colour per card type
data['type'].map do |t|
if (t.eql? 'O')
bg.push(c1)
fg.push(c2)
elsif (t.eql? 'Q')
bg.push(c2)
fg.push(c1)
elsif (t.eql? 'L')
bg.push(c3)
fg.push(c4)
else
bg.push(c4)
fg.push(c4)
end
end
p "colours: #{fg} and #{bg}"
# # set fill colour per card type
# fg = data['type'].map do |t|
# if (t.eql? 'O')
# c2
# elsif (t.eql? 'Q')
# c1
# elsif (t.eql? 'L')
# c4
# else
# c4
# end
# end
# associative image search and/or generation
# https://experiments.runwayml.com/generative_engine/
# https://deepai.org/machine-learning-model/text2img
# generate & collect images
case $img_source
when "t2i"
dlimages = data['name'].map { |i| get_img_t2i i}
when "unsplash"
dlimages = data['name'].map { |i| get_img_unsplash i}
when "pexels"
dlimages = data['name'].map { |i| get_img_pexels i}
else
puts "unknown image source " + $img_source
end
# sharing & colours
background color: bg
rect fill_color: fg , x: '3mm', y: '3mm', width: '32mm', height: '54mm', radius: 0
#rect layout: 'cut' # cut line as defined by TheGameCrafter in economy.yml
#rect layout: 'safe' # safe zone as defined by TheGameCrafter in economy.yml
# in z-order low->high
text str: data['text'], layout: 'description'
png file: dlimages, layout: 'illustration'
png file: dlimages, layout: 'overlay'
text str: data['type'], layout: 'type'
text str: data['name'], layout: 'title'
svg file: data['illustration'], layout: 'card_type'
# output a png of each card
tag = Time.now.strftime('%Y%m%d_%H%M')
save format: :png, prefix: "cards_#{$keyword}_#{tag}_#{$img_source}_", count_format: '%d'
#.. and pdf of the deck on A4
# see also https://squib.readthedocs.io/en/v0.15.0/sprues.html#list-of-sprues
save format: :pdf, file: "deck_#{$keyword}_#{tag}_#{$img_source}.pdf",
width: '297mm', height: '210mm', margin: '20mm',
crop_marks: true,
crop_stroke_width: 0.5
#save_png
#save_pdf
end