About loadImage() method

Hi!!
I have faced a problem in loadImage() function, which the p5.js editor doesn’t load a photos by there url, this is the code.

function setup() {
createCanvas(120, 120);
}

function draw() {
let gender = “Female”;
let birth = 2000;
age = 2021 - birth;

if (age < 8)  
  age = 8;
if (age > 80) 
  age = 80;
	
let delta = (age<12) ? 2 : 5;
let minimumAge = age - delta;
let maximumAge = age + delta;

let url = "https://fakeface.rest/thumb/view?";
url += gender == "All" ? "" : "gender=" + gender.toLowerCase();
url += "&minimum_age=" + minimumAge;
url += "&maximum_age=" + maximumAge;

img = loadImage(url, img => {
  image(img, 0,0,width,height); 
} );

}

Make a complete url and try it in your code

test https://global.discourse-cdn.com/standard10/uploads/processingfoundation1/original/1X/f026ec45c50121b5d28bf43cacf1cded97b4278e.png

I tried, still the same result.

function setup() {
createCanvas(120, 120);
}

function draw() {
let url = “https://thumb.fakeface.rest/thumb_female_26_5ea460d1e2fa4b20ab091ca10c5e1e13197e53b0.jpg”;
img = loadImage(url, img => {
image(img, 0,0,width,height);
} );
}

Are you certain that the image exists? Try typing it into Google search.

this works


let img; 


function setup() {
  createCanvas(120, 120);
}

function preload() {
  // preload() runs once
  
  let url =
    "https://global.discourse-cdn.com/standard10/uploads/processingfoundation1" +
    "/original/1X/f026ec45c50121b5d28bf43cacf1cded97b4278e.png";
  
  img = loadImage(url);
}

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


this as well (not good code imho)



function setup() {
  createCanvas(120, 120);
}

function draw() {
  let url =
    "https://global.discourse-cdn.com/standard10/uploads/processingfoundation1" +
    "/original/1X/f026ec45c50121b5d28bf43cacf1cded97b4278e.png";
  img = loadImage(url, (img) => {
    image(img, 0, 0, width, height);
  });
}

First off you definitely don’t want to put code like that in the draw() function. The draw() function will be run many times per second and with you current code you will be triggering loadImage() every frame, that’s going to make a lot of excess network requests and when you actually draw the images in the callback function passed to loadImage() those calls may happen out of order and in short succession. This is probably what Chrisir meant by “not good code imho.”

The other issue here is a CORS error. Basically that API is not designed to accept requests from arbitrary sources. You can see this if you check the JavaScript console or Network tab in your web browser’s developer tools:

Access to fetch at 'https://fakeface.rest/thumb/view?gender=female&minimum_age=16&maximum_age=26' from origin 'https://preview.p5js.org' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
p5.js:80673 GET https://fakeface.rest/thumb/view?gender=female&minimum_age=16&maximum_age=26 net::ERR_FAILED 302
_main.default.loadImage @ p5.js:80673
mouseClicked @ 271c6326-51bf-41ff-bbab-c9b86c042681:26
_main.default._onclick @ p5.js:78581
index.js:27 
🌸 p5.js says: It looks like there was a problem loading your image. Try checking if the file path (https://fakeface.rest/thumb/view?gender=female&minimum_age=16&maximum_age=26) is correct, hosting the file online, or running a local server. (More info at https://github.com/processing/p5.js/wiki/Local-server)
index.js:27 TypeError: Failed to fetch
    at p5._main.default.loadImage (p5.js:80673:13)
    at mouseClicked (271c6326-51bf-41ff-bbab-c9b86c042681:26:9)
    at p5._main.default._onclick (p5.js:78581:44)

A more detailed reason of why this fails is that when you request this image URL with CORS headers: Sec-Fetch-Mode: cors it response with a HTTP 302 response that does not have any CORS headers (the expected response would be to include Access-Control-Allow-Origin: your-origin or Access-Control-Allow-Origin: * if the request were permitted).

However, there is actually a workaround for this issue. You can bypass the CORS check entirely by creating a <img> tag directly, and then you can use that as the source when drawing the image to your canvas:


function setup() {
  createCanvas(120, 120);
  background('lightgray');
  noLoop();
}

function mouseClicked() {
  background('orange');
  let gender = "Female";
  let birth = 2000;
  age = 2021 - birth;

  if (age < 8) age = 8;
  if (age > 80) age = 80;

  let delta = age < 12 ? 2 : 5;
  let minimumAge = age - delta;
  let maximumAge = age + delta;

  let url = "https://fakeface.rest/thumb/view?";
  url += gender == "All" ? "" : "gender=" + gender.toLowerCase();
  url += "&minimum_age=" + minimumAge;
  url += "&maximum_age=" + maximumAge;

  // There's a warning from p5.js about passing null here, but you have to do this because createImg does not work as documented when passing an empty string for the crossOrigin argument.
  img = createImg(url, "random face", null, () => {
    console.log('image loaded');
    image(img, 0, 0, width, height);
  });
  img.hide();
}

However, once you do this your canvas is “tainted” and you will not be able to utilize any features that load pixel data (for example the p5.js save() function). See: Allowing cross-origin use of images and canvas - HTML: HyperText Markup Language | MDN

3 Likes

Hi Chrisir, your code run without any problem, but with my url, its does not run.
Thanks

Thanks alot @KumuPaul

1 Like

Yes The image is exists.