#!/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 # 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 = "" # where to get images? try "t2i" or "unsplash" or "pexels" $img_source = "unsplash" # 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' # 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 #layouts = ['economy.yml', 'space-layout-1.yml'] layouts = ['space-layout-3.yml'] c1 = '#9f68ed' c2 = '#ed9f68' c3 = '#b5ed68' c4 = '#eeeeee' # colourings... 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