Convert ascii into image?

edited January 2017 in Arduino

Hi everyone! Quick question as I'm learning about processing:

Using a string of values coming in via serial, how can I tell processing to use these consider each number as the value for a pixel in order to create a black & white image?

Here's the code that I have so far... any suggestions/examples would be great!

PImage img;

import processing.serial.Serial;

static final int PORT_INDEX = 0, BAUDS = 9600;
String myString;

void setup() {
  noLoop();
  final String[] ports = Serial.list();
  printArray(ports);
  new Serial(this, ports[3], BAUDS).bufferUntil(ENTER);
}



void draw() {
  // show values coming in via Serial
  // e.g.: 0,0,0,0,0,0,0,0,0,0,255,255,255,255,255...
  //print("Received data: ");
  println(myString);


  // Use the values from serial to build a BLACK & WHITE image
  // image has a size of 20x20 pixels
  // pixel values --> 0 represents black; 255 represents white
  PImage img = createImage(20, 20, ALPHA);      // create a "placeholder" with the correct size
  img.loadPixels();

  // fill the placeholder with white pixels
  for (int i = 0; i < img.pixels.length; i++) {
    img.pixels[i] = color(255);
  }
  img.updatePixels();
  image(img, 17, 17);


  // use values from myString to populate the image pixels
  //  ????

}



void serialEvent(final Serial s) {
  myString = s.readString().trim();
  redraw = true;
}
Tagged:

Answers

  • edited January 2017

    @lucshi09 --

    Please edit your post (gear icon) and format your code by highlighting and pressing CTRL-o.

    Regarding your question:

    how can I tell processing to use these consider each number as the value for a pixel

    1. You can convert a string value "255" to an int value 255 using int() https://processing.org/reference/intconvert_.html

    2. The color() function will interpret a single numeric argument as grayscale. https://processing.org/reference/color_.html

    Here is a sketch to demonstrate. It draws a white background based on the string "255."

    String s = "255";   //  "255"
    int i = int(s);     // = 255
    color c = color(i); // = white
    background(c);
    

    You can also set individual pixels using pixel[], or set():

    This sets a single black pixel in the center of the sketch:

    String s = "0";     //  "0"
    int i = int(s);     // = 0
    color c = color(i); // = black
    set(width/2,height/2, c);
    
  • thank you so much for your message & suggestions. I went ahead and edited my previous post so that the code posts correctly (thanks for the info on how to do this). I also went ahead and implemented your recommendations, including saving the data and reading it in as comma-delimited data. All the data is now correctly stored in an int array.

    However, I'm stuck on trying to have processing to read my data array (where all the values for each pixel is contained) and use this to plot the image.

    Any suggestions on how I can do this? The examples that you provided earlier were of help... but I haven't been able to figure out how exactly to carry out this last step.

    Do you/anyone have any thoughts or examples? Thanks!

    Here's the revised code I have:

    void draw() {
      // show values coming in via Serial
      // e.g.: 0,0,0,0,0,0,0,0,0,0,255,255,255,255,255...
      //print("Received data: ");
    
    
      if (myString == empty) {
        println("No data.");    // don't do anything if no data is coming in
      } else {      // if data arrives, then processing it
        println("I received data:");
        println(myString);
    
    
        // Save incoming data into csv file
        output.println(myString);
        output.flush(); // Writes the remaining data to the file
        output.close(); // Finishes the file
    
    
        // Load text file as a String
        String[] stuff = loadStrings("data.txt");
        // Convert string into an array of integers using ',' as a delimiter
        int[] data = int(split(stuff[0], ','));
    
    
        // Create the image using the values found in "data" 
        // Use the values from serial to build a BLACK & WHITE image
        // image has a size of 20x20 pixels ==> 400 pixels in total
        // pixel values --> 0 represents black; 255 represents white
        PImage img = createImage(20, 20, ALPHA);      // need to create a "placeholder" 
                                                      // with the correct size (is this needed?)
        img.loadPixels();
    
    
        // I'M CONFUSED HERE: how do I load the values in "data" so that
        // they can be plotted as in the image (using "img.updatePixels()" )? 
        //     :-(
    
    }
    
  • Answer ✓

    Not sure why you save and load that data to file in every frame. That might get pretty slow. You can convert that serial-data to int directly and store it in your data-array. But since i don't know your whole code and you say your problem is with the pixels of your image, here is an example with random values instead of real data:

    int imgW = 128;
    int imgH = 100;
    int[] pixValues;
    PImage img;
    
    void setup() {
      size(200, 200);
    
      // create Image
      img = createImage(imgW, imgH, RGB);
    
      // create Array of values
      pixValues = new int[imgW*imgH];
    
      // fill with values
      for (int i =0; i< pixValues.length; i++) {
        pixValues[i] = i%256;
      }
    
      // set pixels of image
      img.loadPixels();
      for (int i =0; i< pixValues.length; i++) {
        img.pixels[i] = color(pixValues[i]);
      }
      img.updatePixels();
    
    
    }
    
    void draw() {
    
      background(0);
      image(img, 50, 50);
    }
    
  • benja, thank you SO much for your clear-cut & simple example! I really appreciate your assistance. It made things so much clearer =)

  • @lucshi09 -- see also the pixels[] reference example for an even simpler illustration of writing values (in this case, just one value over and over) to an image pixel array using a for loop.

Sign In or Register to comment.