We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I made a class so i can load images on a thread. The idea is to display them without having a huge framedrop.
If i comment:
load(filenameIndex);
in the get() method then it works. I only don't understand why it doesn't work without that commented.
Since it should detect that a image is already loaded and therefor not load it.
Any help is welcome.
PImageSequence imgSec;
void setup() {
size(800, 600);
String[] filenames = new String[145-28];
for (int i = 0; i < filenames.length; i++) {
filenames[i] = (i+28)+".png";
}
// filenames, buffersize, threaded
imgSec = new PImageSequence(filenames, 64, true);
imgSec.fillBuffer();
}
// . . . . . . . . . . . . . . . . . . . . . .
void draw () {
image(imgSec.getNext(), 0, 0);
fill(0);
text(frameRate, 20, 20);
}
the class:
import java.util.Arrays;
class PImageSequence extends Thread {
// for the Threading
boolean running;
int wait = 1;
PImage[] imgBuffer;
int bufferSize;
String[] filenames;
// be aware that is has the length of the buffer
int[] loadedIndex;
int filenameIndex;
PImageSequence(String[] filenames) {
createBuffer(64);
setImages(filenames);
// not Threaded!
}
PImageSequence(String[] filenames, int bufferSize) {
createBuffer(bufferSize);
setImages(filenames);
// not Threaded!
}
PImageSequence(String[] filenames, int bufferSize, boolean threaded) {
createBuffer(bufferSize);
setImages(filenames);
if (threaded) start();
}
// . . . . . . . . . . . . . . . . . . . . . .
void start() {
running = true;
super.start();
}
// . . . . . . . . . . . . . . . . . . . . . .
void run() {
while (running) {
if (filenameIndex != -1) {
// load ahead
// never load more then half the buffersize ahead
// this way going back won't cause a huge framedrop
int h_bufferSize = bufferSize/2;
// find the first occurence where preLoadIndex is not the correct fileIndex
for (int i = 0; i < h_bufferSize; i++) {
int checkIndex = (filenameIndex + i) % filenames.length;
println(filenameIndex, checkIndex);
//println(filenameIndex);
//println(filenames.length);
if (load(checkIndex)) {
println("load:", checkIndex);
break;
}
//
}
}
// int preLoadIndex = filenameIndex + h_bufferSize;
// if (preLoadIndex >= filenames.length) preLoadIndex -= filenames.length;
//boolean didLoad;
// for (int i = filenameIndex; i < min(preLoadIndex, filenames.length) ; i++) {
// if(loadedIndex[i] != filenames
// }
//load(preLoadIndex);
// println(filenameIndex, preLoadIndex);
try {
sleep((long)(wait));
}
catch (Exception e) {
}
}
}
// . . . . . . . . . . . . . . . . . . . . . .
void quit() {
running = false; // Setting running to false ends the loop in run()
// IUn case the thread is waiting. . .
interrupt();
}
// . . . . . . . . . . . . . . . . . . . . . .
private void createBuffer(int bufferSize) {
this.bufferSize = bufferSize;
imgBuffer = new PImage[bufferSize];
loadedIndex = new int[bufferSize];
Arrays.fill(loadedIndex, -1);
}
// . . . . . . . . . . . . . . . . . . . . . .
public void setImages(String[] filenames) {
if (this.filenames == null || this.filenames.length != filenames.length) {
this.filenames = new String[filenames.length];
}
for (int i = 0; i < filenames.length; i++) {
this.filenames[i] = filenames[i];
}
// 0 or -1?
filenameIndex = -1;
Arrays.fill(loadedIndex, -1);
}
// . . . . . . . . . . . . . . . . . . . . . .
PImage get() {
filenameIndex = max(filenameIndex, 0);
if (filenameIndex == filenames.length) filenameIndex = 0;
load(filenameIndex);
//println(filenameIndex);
//println();
//println(loadedIndex);
return imgBuffer[filenameIndex % bufferSize];
}
// . . . . . . . . . . . . . . . . . . . . . .
PImage getNext() {
filenameIndex++;
return get();
}
// . . . . . . . . . . . . . . . . . . . . . .
void fillBuffer() {
for (int i = 0; i < min(bufferSize, filenames.length); i++) {
load(i);
}
}
// . . . . . . . . . . . . . . . . . . . . . .
private boolean load(int filenameIndex) {
int bufferIndex = filenameIndex % bufferSize;
if (loadedIndex[bufferIndex] == filenameIndex) return false;
//println("load");
println("load->:", filenameIndex);
imgBuffer[bufferIndex] = loadImage(filenames[filenameIndex]);
loadedIndex[bufferIndex] = filenameIndex;
return true;
}
// . . . . . . . . . . . . . . . . . . . . . .
void clear() {
imgBuffer = null;
filenames = null;
loadedIndex = null;
filenameIndex = 0;
}
// . . . . . . . . . . . . . . . . . . . . . .
}
Answers
What makes you think this is the case? What are the values of every variable in this part of the code when it's loading when you think it shouldn't be? Print statements are your friend here.
I figured it out. It's not possible what i want. It takes often 2 frames time to load an image. So it's only one time the buffer size ahead, after that it has to catch up :(
Also see: http://www.processing.org/reference/requestImage_.html
Thanks, good to know. But also that won't help. Using images with less compression might help. But for now i just create a buffer the size equal to the amount of images i want.