Loading bar for loading image

Hello everyone
(medium level in p5 / English is not my native language…)

I am currently making my website in p5, it is almost finished.
It’s quite simple, a sort of slideshow.

I would like to have a loading bar for loading my images.
For aesthetic reasons but above all for the practical side :
I currently have a small graphics bug when the following image is not loaded.
(when transitioning from one image to another) (these are big images)
(graphic bug disappears when the image is finally loaded)

I would like to have a “loading bar” to visually validate the end of loading the image
and launch the transition.
There is no function in p5 to get the quantity of bytes loaded or the size of the image.

How can I do this? It’s possible?
I searched a little on my side,
but I prefer to ask here before going on a false trail.

Thanks in advance :smiley:
bulbx

Hello @bulbx,

Welcome.

You may want to consider using a callback function.
The callback would tell you when you are done loading.
You may be able to adapt this for your code to proceed after loading.

Code below adapted from:
Image:_Load_and_Display_Image

Code shows time before loading and after.

Cut and paste this over the above code to use the image there:

let img; // Declare variable 'img'.
let t1, t2;

function setup() {
  createCanvas(720, 400);
  t1 = millis();
  img = loadImage('assets/moonwalk.jpg', ready); // Load the image
}

function draw() {
  // Displays the image at its actual size at point (0,0)
  image(img, 0, 0);
  // Displays the image at point (0, height/2) at half size
  image(img, 0, height / 2, img.width / 2, img.height / 2);
}

function ready()
  {
  t2 = millis();
  tmp = str(t1) + ' ' + str(t2);  
  console.log(tmp)  
  }

Reference:
https://p5js.org/reference/#/p5/loadImage

:)

2 Likes

One approach would be to put up a ‘thumbnail’ (scaled down) image on the bar as each image is loaded. The following reference shows how to create different sized images from the same file using resize():
https://p5js.org/reference/#/p5.Image

Ok, thank you both, I’ll look into that.
I will report back after some tests.

(I’m not sure of your solutions because I need to know the weight of each image)
(the images are loaded while viewing the site, not in preloading)
(I load the first image in preloading)

Hey, maybe you want to share the current status of the project or example code? I feel you are asking about something specific and a live example would tell much more

1 Like

Write some code to test this and be sure.
You will not know the size of the image until after loading it.
I tested this with code.

That is fine. Load one at a time and don’t keep reloading in draw.
Consider adding some variables for the state of the loading and control flow of code.

That is ok. I did this as well and used the callback (may not be necessary since it is preload and will test more later).

I built on the example I shared to load one image after another only after each was completed loading. I used a variable called loading and set it to true of false to control the flow of the program and loading.

This can be addressed with the callback and some additional code.

You will not know size until after loading.
You may consider just an animated display saying loading instead of progress which is unknown.

I had around 4ms load times and did not need to add loading animation but could have added that as well.

One step at a time.

:)

Hello,
thank you very much for the details
I’ll look at this and come back quickly with more information.
(I haven’t coded in a while, I did this last year)

2 Likes

Hello,
I’m coming back after making some improvements to my site.

I wasn’t explicit enough with my previous question, it’s my fault.
Since I hadn’t coded in a long time, I was a little confused.

I wanted to have a loading bar that indicates the bytes loaded in real time.
with a callback for the percentage of byte loaded (like on loadSound)

Ok, so that’s not possible
I finally used the loadImage callback and a throbber.
It’s not ideal but it works :slight_smile:

But is it still possible to have a callback [whileLoading] of the image,
in pure javascript within P5 or at the root?

I have another question now :grinning:

When my slideshow looped,
it unnecessarily reloads each image with loadImage.

Is it possible to know if the image is in the browser cache,
to avoid having to run the loading function?

Or I have to load each image into an object,
and then check if this object exists?

bulbx

1 Like
1 Like

Turns out it is possible! See @GoToLoop post.

p5.js is part a larger ecosystem and lots to learn!

I did look up throbber:

:)

Hi,
thank you for your feedback.

I finally created an object where I store the image,
and a boolean to know if the image is loaded or not.

I just have one problem,
Is it possible to pass an argument into the loadImage() callback function?
To be able to assign the boolean to the correct object by passing an id.
(there can be several loadImages happening at the same time…)

Because this doesn’t seem to work, I get an error message.
“loadImage() was expecting function(p5.Image) for the second parameter,
received an empty variable instead.”

(the variable is not empty…)
and it launches the function directly without waiting for the loading to finish.

let imagesN = [];

function ImageN() {
  this.image_file;
  this.loaded = false;
}
function nextImageLoading() {
  imagesN[next_id] = new ImageN();
  imagesN[next_id].image_file = loadImage("images/" + data.c1[next_id[0]], nextImageLoaded(next_id));
}  

function nextImageLoaded(_next_id) {
  imagesN[_next_id].loaded = true;
}  

or maybe there is another way to do it,
but it seemed good to me.
bulbx

You can use a counter to represent how many images are currently being loaded:

var counter = 0

function nextImageLoading() {
  ++counter;
  imagesN[next_id] = new ImageN;
  imagesN[next_id].image_file = loadImage("images/" + data.c1[next_id[0]], decreaseCounter);
}

function decreaseCounter() { --counter; }  

Also, loaded images have both width & height greater than 1.

2 Likes

Thanks GoToLoop

(I almost went crazy yesterday, after changing everything,
only to finally realize that it didn’t work because of the argument)

After a good night’s sleep,

I realized that I could put the loadImage function in the imageN object.
That way I’m sure I have something clean with a id.

You can have a function that checks if an image is fully loaded like this:
const isImgReady = img => img.width > 1;

1 Like