Unable to update pixels from text file containing pixel locations

Hi all,
I wrote a program in Processing which writes the 1D coordinates of black pixels in an image to a text file.

I wrote a second program which should read the text file and recreate the black pixels on a white image to verify the functionality of script #1

The problem is that the second program which should recreate the black pixels on a white image is not doing so.

For the first script, The user opens the gui, hits 2 to open the file browser, then loads a file. The code resizes the file and changes it to black and white. The code then scans for black pixels and writes the black pixel coordinates to a text file with one coordinate per line.

The second script should simply recreate the original image by adding black pixels in those coordinates to a white image. This is to verify the functionality of script #1.

Here’s the code for script #1:

boolean stopt = false;
boolean writin = false;
PrintWriter output;
PImage input;
int limiter = 0;
void setup() {
  size(350, 500);
// Create a new file in the sketch directory
 output = createWriter("DIRECTIONS.TXT");
}
void draw(){
  background(0, 25, 51);
  //show processed image here.
  text("Click and type '1' to stop", 10, 440);
   text("Click and type '2' to convert image to command file", 10, 460);
    text("Copy DIRECTIONS.TXT to the printer's memory card after", 10, 480);
    if (stopt) {
      writin = false;
       text("finished or stopped.", 10, 420);
    }
    if (!stopt) {
      text("                          ", 10, 420);
    }
    if (writin) {
      stopt = false;
      text("translating image to printer commands", 10, 420);
    }
    if (!writin) {
      text("                          ", 10, 420);
    }
  if(input!= null){
    input.resize(300, 300);
    input.filter(THRESHOLD, 0.5);
    image(input, 10, 10, 330, 330);

     input.loadPixels();
  //Loop through each pixel (use image size instead of pixels.length!)
  if (limiter <= 90000) {
for (int x = 0; x < width; x++ ) {
  for (int y = 0; y < height; y++ ) { 
    color black = color(0, 0, 0);
    color c = get(x, y);
    if (c == black) {
    int loc = x + y * width;
     output.println(loc);
     writin = true;
  }
}
limiter = limiter + 1;
}

  }
  else if (limiter > 90000) {
    stopt = true;
  }
}
}

void imageSelected(File selection) {
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
  } else {
    input = loadImage (selection.getAbsolutePath());
  }
}
void keyPressed() {
  if (key == '1') {
  output.flush(); // Writes the remaining data to the file
  output.close(); // Finishes the file
  stopt = true;
  //exit(); // Stops the program
}
if (key == '2') {
  selectInput("Select an image to process", "imageSelected");
  }
}

And here’s the code for script 2:

PImage input;
int tex = 0;
void setup() {
  input = loadImage("white.png"); //mostly blank image in sketch folder 300 x 300 px.
  size (300, 300);
}
void draw() {
  loadPixels();
  input.loadPixels();
  String[] lines = loadStrings("direct.TXT"); //text file with each line being a 1D pixel coordinate in linear order.
  for (int i = 0; i < lines.length; i++) {
    tex = Integer.parseInt(lines[i]);
    for (int x = 0; x < width; x++ ) {
      for (int y = 0; y < height; y++ ) { 
        color black = color(0, 0, 0);
        //color c = get(x, y);
        int loc = x + y * width; 
        if (loc == tex) {
          pixels[loc] = black;
        }
      }
    }
  }
  updatePixels();
}

Hi Socraticbot,
Without going too much into detail about the code, the first thing I notice is that in the second script, the image drawing function is written in draw(), which loops. Try putting that whole block of code in the Setup(). Also, the first

is unnecessary. Also (this may not matter), I think the .TXT should be lowercase (.txt). Again, I’m not sure about that second point. Please try this out and let us know if that works. Also, if it doesn’t work, can you tell us what the program is actually doing?
Good luck.

  • Trilobyte

You don’t need an empty image, input = createImage(300, 300, RGB); will also work.
I can’t figure out what’s wrong, so I’m going to recreate both scripts :slight_smile:

Thanks in advance DongKingKong0!

Finally got it to work :slight_smile:
Here’s the code.
Script 1:

PImage input;// The selected image
String[] output;// The output file

void setup(){
  size(300, 300);
  output = new String[1];
  output[0] = "";// Avoid "null" at beginning
  selectInput("Select an image to process", "select");
}

void select(File selection){
  if(selection == null){
    exit();// exit if the input is null
  }else{
    input = loadImage(selection.getAbsolutePath());// load selected image
    input.resize(width, height);// resize
    input.filter(THRESHOLD, 0.5);// make everything black and white
    
    input.loadPixels();
    for(int i = 0; i < input.pixels.length; i ++){// loop through all pixels
      if(input.pixels[i] == color(0)){
        output[0] += i + "\n";// if the pixel is black, write the position to the file
      }
    }
    saveStrings("DIRECTIONS.TXT", output);// save everything
    println("done");
  }
}

Script 2:

String[] input;// input file

void setup(){
  size(300, 300);
  input = loadStrings("DIRECTIONS.TXT");// load DIRECTIONS.TXT
  
  background(255);// clear image
  
  loadPixels();
  for(int i = 0; i < input.length; i ++){
    pixels[int(input[i])] = color(0);// for each line in the input file, set that pixel to black
  }
  updatePixels();
  println("done");
}

I’m more familiar with saveStrings(), so I used that instead of a PrintWriter.

1 Like

I don’t really know what was wrong with your code, but you don’t need to loop through the file and then through all pixels, since the pixels array has only one dimension.
Sometimes it’s better to keep things simple :wink:

1 Like

Because you asked, I decided to look at the code again :grin:

if (limiter <= 90000) {

This will always return true, since the limiter is increased in a for inside the if statement.

for (int x = 0; x < width; x++ ) {
for (int y = 0; y < height; y++ ) {

I think this is the main problem of your code.
You use width and height here, which is the size of the window (350 * 500). Easy fix: replace width with input.width.

The second issue is that you have three for statements, that means you need (worst case, completely black image) 300^4 = 8,100,000,000 loops through your program per frame. That would just cause the sketch to take a very long time to render the image. That’s why you don’t see anything in your second sketch.

Anyway, I hope that helped you and that you understand it now :wink:

1 Like

I don’t really get why you’re using a spiral path…?

Hey, @socraticbot it‘s not very polite that you delete your posts because the helpful answers are then meaningless.

Socrates wouldn’t approve.