Home > Back-end >  Why do i get error in processing pixelation?
Why do i get error in processing pixelation?

Time:04-01

I've been trying to copy a p5 script into processing for a school project but I cant completely figure it out. Here you can find the original script : https://www.youtube.com/watch?v=KfLqRuFjK5g

I keep getting this error : ArrayIndexOutOfBoundsException: Index 5832960 out of bounds for length 5801040.

Thanks in advance!

PImage img; // creates image variable

int size = 7; // element size

int startx = 0; // starting x coordinate
int starty = 0; // starting y coordinate

void preload() {
}

void setup() {
  size(500, 400); // creates canvas
  
  img = loadImage("Dubbel_augurk-01.jpg"); // preloads Virginia picture
  img.loadPixels(); // loads image
  img.resize(displayWidth, 0); // resizes image to window size
  img.updatePixels(); // updates image

}


void draw() {
  clear();
  background(0);

  int size = floor(map(mouseX, 0, width, 7, 40)); // maps mouseX value to element size

  for (var starty = 0; starty < img.height; starty  ) { // creates pixel index
    for (var startx = 0; startx < img.width; startx  ) {
      var index = (startx   starty * img.width) * 4;
      var r = img.pixels[index   0];
      var g = img.pixels[index   1];
      var b = img.pixels[index   2];

      //var bright = ((1 * r)   (0.59 * g)   (0.11 * b)); // sets pixel value to adjusted grayscale

      fill(r,g,b); // fills element with adjusted grayscale

      rect(startx, starty, size, size);

      startx = startx   size -1; // set new startx value
    }
    starty = starty   size -1; // set new starty value
  }

}

CodePudding user response:

There's a difference between how p5.js (html canvas) stores pixels[] and how Processing's Pimage stores pixels[].

While they're both 1D arrays, p5.js pixels[] uses 4 values per pixels (e.g. [r1,g1,b1,a1, r2,g2,b2,a2, ...], etc.) and Processing uses 1 value per pixel (e.g. [pixel1ARGB, pixel2ARGB, etc.] for ARGB image / [pixel1RGB, pixel2RGB, etc.] for RGB images).

This is why there's a * 4 on this line in p5.js:

var index = (startx   starty * img.width) * 4;

Hence the array index out of bounds error: the p5.js pixels[] has 4 times more elements than pixels[] in Processing.

Remember to also change the data types (you can't use var in Processing(java)).

Removing the unused(shadowed) startx,starty variables at the top and slightly renaming them as per Java naming conventions, your snippet would look like this:

PImage img; // creates image variable

int size = 7; // element size

void setup() {
  size(500, 400); // creates canvas
  
  img = loadImage("Dubbel_augurk-01.jpg"); // preloads Virginia picture
  img.loadPixels(); // loads image
  img.resize(displayWidth, 0); // resizes image to window size
  img.updatePixels(); // updates image

}


void draw() {
  clear();
  background(0);

  int size = floor(map(mouseX, 0, width, 7, 40)); // maps mouseX value to element size

  for (int startY = 0; startY < img.height; startY  ) { // creates pixel index
    for (int startX = 0; startX < img.width; startX  ) {
      int index = (startX   startY * img.width);
      int pixelRGB = img.pixels[index];

      fill(pixelRGB); // fills element with adjusted grayscale

      rect(startX, startY, size, size);

      startX = startX   size -1; // set new startX value
    }
    startY = startY   size -1; // set new startY value
  }

}

(Note: this code isn't tested, but hopefully it illustrates the points on pixel indexing)

Bare in mind, the main point of the video tutorial was on accessing/reading individual pixel values and using them in some way (e.g. mapping brightness to shape properties (circle size, line thickness, triangle colour, etc.)).

If you simply want to display a low-res version of the image and don't care about pixel values, it might be simpler to downsample the image (resize smaller), but render at the original size (or larger) with no aliasing (to get that crisp pixel art look instead of the blurry aliasing).

Here's a basic example you could run (remember to drag and drop the same "Dubbel_augurk-01.jpg" image on top of this sketchh too):

PImage img; // creates image variable

int downScale = 7; // how many times to scale the image down

void setup() {
  size(500, 400); // creates canvas
  
  // disable aliasing
  noSmooth();
  
  img = loadImage("Dubbel_augurk-01.jpg"); // preloads Virginia picture
  img.resize(img.width / downScale, img.height / downScale); // resizes image  
}


void draw() {
  background(0);

  int size = floor(map(mouseX, 0, width, 7, 40)); // maps mouseX value to element size

  image(img, 0, 0, img.width * size, img.height * size);

}

(There are more options out there, but a bit more advanced (for example using texture(), beginShape(), vertex(x, y, u, v) and aliasing again to scale the texture coordinate or using a fragment shader (via PShader))

  • Related