Fast loading images directly from Disk

edited April 2018 in How To...

Hi,

is there a way to sequencially load images directly from disk with realtime perfomance? loadImage is very slow, and I would like to avoid preloading the images first.

I could do this with old good Flash with Full HD imagery in realtime, so it has nothing to do with my disk performance.

Thanks for any hints Tom

Answers

  • sequencially load images directly from disk

    More details. How many images do you want to load? Do you want to process images by batches? Or do you want to load all the images? Wait, you said you don't want to load all the images in setup in the first place. Scratch my last question. We still need to know more details... what model do you envision using.

    Kf

  • Hi, thanks for reply. I would like to load i.e.300 frames, but in a sequence, so only show 1 image per frame and tangle through the image sequence. So if I perform loadImage per frame in draw I probalbly get a frameRate of 8 fps which is to slow, I would like to get at least 30 fps and liquid display.

    So one image per frame :-)

    Thansk Tom

  • Something tells me Flash wasn't quite doing what you think it was ... but anyway, a sequence of real-time images is also, er, a video. Depending on what you want to do, an MJPEG file might be a better way to handle this. This saves on overhead of opening and closing files. As well as the video library, I've seen various plain Java loaders for MJPEG streams that might be adaptable.

  • Hi, yes the image sequence is equal a video, but I get images in a regular time step and I would like to cycle them in realtime. loadImage seems to be very slow compared the loader in Flash.

  • What exactly are you doing? What does "get images in a regular time step" actually mean? From where?

    Just looked at the code for loadImage - there are some things that you might be able to work around to speed it up a bit if you know for sure the data format / pixel format. What format are your images?

  • I get images .jpg (1920x1080 px) delivered on my server every minute. So I would like to continously cycling thru all images and play them like a movie. What could I do for workarround?

  • ... delivered on my server every minute.

    Is there a fixed folder where all of those delivered images are saved?

  • Hi, yes a fixed folder on my local machine. They are stored in a folder on a fast SSD.

  • Does this show a faster way of loading image? I would like to avoid preloading in setup.

  • No. Just a way to check whether a new File has arrived by checking lastModified(). :-\"

  • :-) thanks FileListing in a separate thread is no problem. I am just surpriesed how slow loadImage is. Even if I preload all files using requestImages and when all loaded I cycle through the PImage Array, it does not play smoothly the first time, the secound loop is ok then. But if I would like to cycle through 1000 frames, preloading takes forever. Why is loadImage so slow?

  • Ru reloading the same images? You should keep the 1s you've loaded.
    Unless memory is running low. :-S

  • I would reload every frame again and again. I would like to avoid pre loading, because I need to play imidiately when I start the application. I do not understand, why processing does load so slow a HD image while processing has an overall very good performance.

  • I will later post an example :-)

  • delivered on my server every minute

    You are loading the images on the server side? I am lost. Could you provide a mcve of your approach? Just to clarify, is this Processing Java or you are processing the images on the server side or retrieving the images from a server? If the latter, are you using loadImage or requestImage?

    Kf

  • "delivered on my local server which I have a fiber channel connection" It is like loading the images from a fast local drive. I will use Processing Java. I tried loadImage and requestImage I will post an example later

  • Don't load images 60 times a second if they are only changing once a minute. That's loading them 3659 times too many.

  • @tom_tm - the workarounds I was thinking (aside from caching some images as others have described)

    • look at using the ImageIO library in Java directly. Keep a single TYPE_INT_RGB BufferedImage, and pass that into a PImage - this should wrap the same pixels array - see https://github.com/processing/processing/blob/master/core/src/processing/core/PImage.java#L299 draw each image you load into the BufferedImage, probably with a call to PImage loadPixels() updatePixels() either side

    • look for a faster Java JPEG loader (Google suggests a few options) and do the same trick to update the pixels array directly.

    • use the video library - the GStreamer PlayBin backing the Video component is quite happy to play JPEG files as much as movies! It's pretty fast too.

  • Hi, thank you very much for this infos. I will check the GStreamer PlayBin, I hope I will understand it.

    I have to try :-)

  • @tom_tm actually scratch the video library idea, sorry. Just checked and it looks like the location property isn't exposed for some reason in the video library so this won't work. Shame! Without that the overhead will probably be too much.

  • I bet money that he's calling loadImage in draw, every frame, and that's the problem. It just needs some logic in there to use the current image until the new one is available.

    Post some code.

  • (But not much money)

  • @koogs it is both the problem and what he wants to do (cycle through the whole folder).

  • edited April 2018

    Hi, here is my code I use with preloading the images and also push the images to the graphics card as well, otherwise it won't run fluid the first loop. Is there a faster way to preload, or is it possible to run thrugh the image sequence in realtime without preloading first?

    here you can download the project with the image sequence http://www.ayashmi.com/RT/ImageLoader_pde.zip

    //Number of Frames
    int num = 100;
    PGraphics  sequence;
    
    boolean allFramesLoaded = false;
    boolean check = true;
    boolean play = false; 
    PImage[] imgs = new PImage[num];
    int [] checkLoadedArray = new int[num]; 
    
    int counter = 0; 
    
    float timeInterval = 5; 
    float lastTimeCheck; 
    
    void setup() {
    
    size(1920, 1080, P2D);
    frameRate (25); 
    
    
    sequence = createGraphics(width,height,P2D);
    
    
    
    //preload all images
    
    for (int i = 0; i < num; i++) {
        imgs[i] = requestImage("test"+nf(i, 4)+".jpg");
    }
    
    
    
    }
    
    
    
    void draw() {
    
    
      if (!play) {
    
        runTimer(); 
    
    
    }
    
      if (play) {
    
    
       sequence.beginDraw(); 
       sequence.image(imgs[counter], 0, 0);
       sequence.endDraw();
    
       image(sequence,0,0);
    
    
      } else {
    
        image(imgs[0], 0, 0);
      }
    
      counter ++;
    
      if (counter>num-1) {
          counter = 0;
      }
    
    
    
    }
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    
    void runTimer (){ 
    
    if (millis () > lastTimeCheck + timeInterval) {
       lastTimeCheck = millis(); 
    
       check(); 
    
    }
    
    }
    
    //check if all Frames are loaded and already push it to videocard memory
    void check () {
    
    allFramesLoaded  = true; 
    
    
    
    for (int i = 0; i<num; i++) {
    
    
     if (imgs[i].width == 0) {
    
          checkLoadedArray[i] = 0;
    
          println("not_loaeded"+i); 
        } else {
    
    
       checkLoadedArray[i] = 1;
    
       sequence.beginDraw(); 
       sequence.image(imgs[i], 0, 0);
       sequence.endDraw();
       image(sequence,0,0);
    
    
    
       println("loaded"); 
    
        }
    
    
    
         if (checkLoadedArray[i] == 0) {
            allFramesLoaded  = false;
            play = false; 
         }
    
    
    
    
    
    
    
    if (allFramesLoaded){
    
           counter = 0;
           play = true;  
         }
      } 
    

    }

Sign In or Register to comment.