noLoop not working the way I expected

I have a simple sketch that opens and image, samples the pixels and redraws them with circles at set intervals.

It works great in a loop but I only want it to process the image then stop. When I use the noLoop(); option in setup my sketch dosen’t get beyond asking for the file. If I don’t use noLoop(), it works but just keeps looping and processing.

My code below. Any help would be appreciated.

Thanks,

Phil

import processing.svg.*;

//changes these 2 values to get the image you like

float dotSmall = 6 ;
int space = 4;


int skipX = int(dotSmall)+space ;

int dotLarge = int (dotSmall) ;


import javax.swing.*; 
import java.util.*;
boolean fileSelected;

String path;
PImage img;  
int skipY = skipX;


void setup() { 

  background(0);
  noStroke();
  fill(0);
  colorMode(HSB); 
  ellipseMode(CORNER) ;
  size (100, 100);

  selectImage(); // select an image to process
  
  noLoop();
}


void draw() {
  if (path != null) // Processing has a file to process.
  {
    
      println("starting");
      img = loadImage(path);   
      int sx = img.width;
      int sy = img.height;
      surface.setResizable(true);
      surface.setSize(sx, sy);
      String svgPath = path+".svg";
      beginRecord(SVG, svgPath);

      for (int x=1; x < sx; x=x+skipX) {
        for (int y=1; y < sy; y=y+skipY) {

          color c = img.get(x, y);
          float bright= brightness(c);
          int b = round (bright);
          float dotSize = (map(b, 0, 255, dotLarge, dotSmall));
          fill(c);
          circle(x, y, dotSize);
        }
      }

      endRecord();
      println("finished");
   
  }
}





void selectImage()
{
  selectInput("Select a movie to play:", "fileSelected");
}


void fileSelected(File selection) 
{
  if (selection != null) 
  {

    path = selection.getAbsolutePath();
    fileSelected = true;
    println("User selected " + path);
  }
}

Ok… I added some debugging and have uncovered what could be the issue.

If I run the sketch you will “started draw” printed when in reality I am hoping for it to not start draw() until after a file is chosen.

I think the way I am choosing my file is what is causing my issues but am unsure of another way.

Phil

import processing.svg.*;

//changes these 2 values to get the image you like

float dotSmall = 6 ;
int space = 4;


int skipX = int(dotSmall)+space ;

int dotLarge = int (dotSmall) ;


import javax.swing.*; 
import java.util.*;
boolean fileSelected;

String path;
PImage img;  
int skipY = skipX;


void setup() { 

  background(0);
  noStroke();
  fill(0);
  colorMode(HSB); 
  ellipseMode(CORNER) ;
  size (100, 100);
   
  noLoop();
}


void draw() {
   selectImage(); // select an image to process
    println("starting Draw");
  if (path != null) // Processing has a file to process.
  {
    
      println("Starting main loop");
      img = loadImage(path);   
      int sx = img.width;
      int sy = img.height;
      surface.setResizable(true);
      surface.setSize(sx, sy);
      String svgPath = path+".svg";
      beginRecord(SVG, svgPath);

      for (int x=1; x < sx; x=x+skipX) {
        for (int y=1; y < sy; y=y+skipY) {

          color c = img.get(x, y);
          float bright= brightness(c);
          int b = round (bright);
          float dotSize = (map(b, 0, 255, dotLarge, dotSmall));
          fill(c);
          circle(x, y, dotSize);
        }
      }

      endRecord();
      println("finished");
   
  }
}





void selectImage()
{
  selectInput("Select a movie to play:", "fileSelected");
}


void fileSelected(File selection) 
{
  if (selection != null) 
  {

    path = selection.getAbsolutePath();
    fileSelected = true;
    println("User selected " + path);
  }
}

Hi! the problem is that draw is called no matter if the file is already selected. It means that

  1. run the program
  2. dialog opens
  3. (before you select a file) draw is called, and since path is empty, it will skip the entire block and finishes
  4. you select a file
  5. draw is not called anymore because of noLoop

I think the easiest way to “fix” it is to move noLoop after the image is drawn

...
      endRecord();
      println("finished");
      noLoop();
...

by the way the project is run by volunteers and it would be nice if you refrain from making ironic comments on the features (I personally found the title is slightly offensive) :slight_smile:

1 Like

you can lose the draw call altogether and unless you are reloading the svg for display you can lose the surface resize and just close the app

import processing.svg.*;
import javax.swing.*; 
import java.util.*;

float dotSmall = 4;
int space = 4;
int skipX = int(dotSmall)+space;
int dotLarge = 8;
boolean fileSelected;
String path;
PImage img;  
int skipY = skipX;

void setup() { 
    selectInput("Select an image", "fileSelected");
}

void fileSelected(File selection) 
{
  if (selection != null) 
  {
    path = selection.getAbsolutePath();
    img = loadImage(path); 
    int sx = img.width;
    int sy = img.height;
    surface.setResizable(true);
    surface.setSize(sx, sy);
    String svgPath = path.substring(0, path.length() - 4) + ".svg";
    beginRecord(SVG, svgPath);
    
    background(0);
    noStroke();
    colorMode(HSB); 
    ellipseMode(CORNER);
    
    for (int x = 1; x < sx; x += skipX) {
        for (int y = 1; y < sy; y += skipY) {
            color c = img.get(x, y);
            float bright= brightness(c);
            int b = round (bright);
            float dotSize = (map(b, 0, 255, dotSmall, dotLarge));
            fill(c);
            circle(x, y, dotSize);
        }
    }
    endRecord();
  }
}

Thanks for the suggestion @micuat and I’m sorry if my lame pun offended anybody.

Phil

@micuat I tried your solution and it worked great, thanks.

The one issue I have is that because my surface starts at 100,100 pixels when my image is drawn, I only see a really low quality cropped image after the sketch runs.

Basically I read the size of the image and want to change the surface size prior to drawing the dots but currently it does the opposite. It seems to draw the dots based on the 100x100 then change the size of the surface.

The SVG looks correct.

Any ideas?

Thanks,

Phil

no problem! you need to use surface to change the size later. Use surface.setResizable

then you can use surface.setSize(w, h) anywhere to change the canvas size later.

@micuat That’s what I currently have at the start of my draw()

img = loadImage(path);   
      int sx = img.width;
      int sy = img.height;
      surface.setResizable(true);
      surface.setSize(sx, sy);

The surface does resize but it scales all the dots I have already drawn. I need it to set the size before I start drawing the dots.

Hope that makes sense.

Thanks again.

I’m gonna start a new thread about my surface resize issue as you have solved the noLoop() issu I was having…

Thanks again… much appreciated.

Phil