Abdullah Zameek
Abdullah Zameek

Reputation: 21

Load Image Generated From A Function in p5.js canvas

I'm trying to load an image that is returned as a result of a function in a library called gaborgen.js

The idea is that I should be able to generate a Gabor patch image using this library and then I need to store this in an image variable in p5, and display it on the canvas.

The way the library works is that it has a function gaborgen() that takes in two parameters, so gaborgen(50,50) would return a Gabor patch with those attributes. The way the library works is that it returns the image as a base64 PNG.

I tried to load the image as follows, but it failed. The resulting sketch is just a blank screen.

var img;

function setup() {
 createCanvas(640, 360);
 img = createImg(gaborgen(50,40));

}

function draw(){
 background(0);
 image(img, 0, 0, img.elt.width, img.elt.height);
}

The gaborgen() function in the Gaborgen.js library is as follows;

gaborgen = function(tilt, sf) {
  var a, aspectratio, b, contrast, gab_x, gab_y, gridArray, i, j, m, multConst, phase, preSinWave, ref, reso, sc, scaledM, sf_max, sf_min, sinWave, tilt_max, tilt_min, varScale, x, x_centered, x_factor, y, y_centered, y_factor;
  if ((tilt > 100 || tilt < 1) || (sf > 100 || sf < 1)) {
    console.log("ERROR: gaborgen arguenment input out of bounds");
  }
  reso = 400;
  phase = 0;
  sc = 50.0;
  contrast = 100.0;
  aspectratio = 1.0;
  tilt_min = 0;
  tilt_max = 90;
  sf_min = .01;
  sf_max = .1;
  tilt = rescale_core(tilt, tilt_min, tilt_max, 1, 100);
  sf = rescale_core(sf, sf_min, sf_max, 1, 100);
  x = reso / 2;
  y = reso / 2;
  a = numeric.cos([deg2rad(tilt)]) * sf * 360;
  b = numeric.sin([deg2rad(tilt)]) * sf * 360;
  multConst = 1 / (numeric.sqrt([2 * pi]) * sc);
  varScale = 2 * numeric.pow([sc], 2);
  gridArray = numeric.linspace(0, reso);
  ref = meshgrid(gridArray), gab_x = ref[0], gab_y = ref[1];
  x_centered = numeric.sub(gab_x, x);
  y_centered = numeric.sub(gab_y, y);
  x_factor = numeric.mul(numeric.pow(x_centered, 2), -1);
  y_factor = numeric.mul(numeric.pow(y_centered, 2), -1);
  preSinWave = numeric.add(numeric.add(numeric.mul(a, x_centered), numeric.mul(b, y_centered)), phase);
  i = 0;
  while (i < reso) {
    j = 0;
    while (j < reso) {
      preSinWave[i][j] = deg2rad(preSinWave[i][j]);
      j += 1;
    }
    i += 1;
  }
  sinWave = numeric.sin(preSinWave);
  m = numeric.add(.5, numeric.mul(contrast, numeric.transpose(numeric.mul(numeric.mul(multConst, numeric.exp(numeric.add(numeric.div(x_factor, varScale), numeric.div(y_factor, varScale)))), sinWave))));
  scaledM = rescale(m, 0, 254);
  return numeric.imageURL([scaledM, scaledM, scaledM]);
};

Any idea how I can load a base64 PNG returned by a function into p5.js like this?

Upvotes: 1

Views: 1704

Answers (1)

Kevin Workman
Kevin Workman

Reputation: 42176

You can use a base-64 encoded image directly in P5.js by passing the string directly into the loadImage() function. Here's an example:

var img;

function setup() {
  createCanvas(400, 400);
  img = loadImage('data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==');
}

function draw() {
  background(220);
    image(img, 0, 0, width, height);
}

Notice the data:image/png;base64, part of the argument.

I don't know what gaborgen() function returns, so you're going to need to do some debugging to figure out exactly where your code breaks down. Work forward in smaller steps and check your developer tools for errors.

Upvotes: 3

Related Questions