For this week’s assignment we had to create an electronic generated -omancy: a divination method that could forecast the future based on an object, user interaction or random selected event. Thus, I created a tool that, from uploading your ancestors b&w old pictures, you can see a specific prediction related to the data collected from that image. I called it ANCESTOR PHOTOMANCY.

So a divination based in your astrology assume that the stars interfered with the moment you were born creating specific traits that shape who you are and your destiny. Accordingly, I started to think about tangible aspects of nature and history that definitely change your life and are responsible for our very own existence – and consequently our future.

I feel it is indeed crazy, even though very obvious, to stop and think that we are here being who we are because some people in the past lived the way they did – people we didn’t get to know, have very little knowledge about their stories and personalities, and, of course, if you go way back then, people that we can’t even name, trace and know their origins.

So, I asked my mother in Brazil to scan and send me some pictures of my old relatives.

It’s so beautiful the aesthetics of those images. The posed way they appeared in the images, the clothes, the colors of the printing. It’s funny to think there is a bit of each one of those barely strangers inside me, and magic somehow. So, for this divination ritual I decided to play with the aspects of the images and connect that to a Tarot reading API and see what that could tell me about my future.

—- of course, this exercise has a playful approach so I am not really looking forward to forecast my future, but to play with the concept and explore electronic divination experiments.

The easiest way to analyze images is through brightness, and if you have B&W images that’s a very easy thing to do. So, I found this algorithm inspired in a project made by a colleague that would give me a number from 0 to 100 for qualifying the brightness of the images. Once having this number, I send it to the tarot reading API that will assign a correspondent Tarot Card and choose a random fortune_telling” string from the 3 options on that specific card.

Here you can check the code:

//not so serious ancestor-picromancy engine to give you a glimpse of what the future holds
// using these tarot explanations

let myImage;
let pix;
let rank; // king: rank 25, queen: rank 24, knight: rank 23, page: rank 22;
let brightness;
let fortune_array = [];

function preload() {
myFont = loadFont('assets/Kristi-Regular.ttf');
myImage = loadImage("pics/ancestor.jpg");
title = loadImage("etch.png");
data = loadJSON("")

function setup() {
createCanvas(windowWidth, windowHeight);
translate(windowWidth / 2, windowHeight / 2);
image(title, 0, 0);
text("ASK YOUR ANCESTORS TO KNOW", windowWidth/3.25, windowHeight/3.6 - myImage.height*0.1/2 - 45);
text("WHAT THE FUTURE HOLDS", windowWidth/3.5, windowHeight/3 - myImage.height*0.1/2 - 45);
translate(windowWidth / 2, windowHeight / 2.1);
image(myImage, 0, 0);
//get average brightness of image and match it to card rank in tarot set;
console.log("rank: " + rank); //can somehow not access "rank" as a global variable ...???
// search as well for king, queen, knight and page ranks
if (rank > 21){
extra_ranks = ['page', 'knight', 'queen', 'knight'];
rank = extra_ranks[rank - 22];
let fortunes = data.tarot_interpretations[rank].fortune_telling[round(random(data.tarot_interpretations[rank].fortune_telling.length -1),0)];
text(fortunes + ".", windowWidth/2, windowHeight/1.2)
let fortunes = data.tarot_interpretations[0].fortune_telling[0];

// function taken from
// converts each color to gray scale and returns average of all pixels
// brightness: 0 (darkest) and 255 (brightest)
function getImageLightness(imageSrc,callback) {
img = document.createElement("img");
img.src = imageSrc; = "none";

let colorSum = 0;

img.onload = function() {
// create canvas
let canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;

let ctx = canvas.getContext("2d");

let imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
let data =;
let r,g,b,avg;

for(let x = 0, len = data.length; x < len; x+=4) {// noprotect.
r = data[x];
g = data[x+1];
b = data[x+2];

avg = Math.floor((r+g+b)/3);
colorSum += avg;

brightness = Math.floor(colorSum / (this.width*this.height));
// map & round brightness to 0 - 10 value of Tarot cards
brightness = round(, 255, 0, 25), 0);
rank = brightness;
callback(brightness, rank);


// map 0 - 255 average brightness values to 0 - 10 Tarot card ranks
// (taken from = function (in_min, in_max, out_min, out_max) {
return (this - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

// round values
// (taken from
function round(value, decimals) {
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);

// append all entries into array for ranks
// (not taken from anywhere ;)
function find_ranks(key){
for(i = 0; i < data.tarot_interpretations.length; i++) {
if (data.tarot_interpretations[i].rank == key){
console.log('found matching rank in array ' + i);
console.log('found matching rank in arrays ' + fortune_array)
rank = fortune_array[round((random(fortune_array.length -1)),0)];
console.log('selected rank in array ' + rank)

// go fullscreen and resize if necessary
function windowResized() {
resizeCanvas(windowWidth, windowHeight);

For now I uploaded the images right on the folder directly in the code. A *must* for the  iteration would add a user input in the browser with the CTA “upload your ancestors B&W image here” so everyone can actually use it.

Below you can check what my ancestors said about my future in this experiment.

Angelo and Sara think that I should reconsider my decisions –

Francisco disagrees, and has a more positive view –

Pedro, Sara and Mauricio are telling me to watch out —

Share this Post

Leave a Reply

Your email address will not be published. Required fields are marked *