Get() returns an empty pixels array

Hi, I want to show the cropped picture created by shuffling the certain portion of the original videocam image. “capture.get()” function in draw() works correctly, but because the returning object has an empty array as the property “pixels”, I can’t use it to shuffle the object or the array. Could anyone help me with this? Thank you so much in advance!

function setup() {
  createCanvas(400, 300);
  background(150);  
  noLoop();

  capture = createCapture(VIDEO);
  capture.loadPixels();
  capture.size(width,height);
  capture.hide();

  selected = createImage(50, 50);
  selected.loadPixels();
}

function draw() {
  image(capture, 0, 0)
  
  selected = capture.get(100, 100, 150, 150)
  console.log(selected.pixels)//returning []
  selected = pixelShuffle(selected)//shuffling the array
 
  image(selected, 50, 50) //not showing the shuffled version of the picture
}

Hello, @k5221, and welcome to the Processing Community .

You may try out the following as a model for your code. Note that all the instructions that modify the selection are confined to the pixelShuffle function. As written here, the function does not shuffle the pixels, but instead changes their color. Of course, you will need to revise the code within that function to conform to your needs.

let capture;
let selected;
function setup() {
  createCanvas(400, 300);
  background(150);  
  capture = createCapture(VIDEO);
  capture.hide();
  selected = createImage(50, 50);
}

function draw() {
  image(capture, 0, 0);
  selected = capture.get(100, 100, 150, 150)
  selected = pixelShuffle(selected);//shuffling the array
  image(selected, 50, 50) //not showing the shuffled version of the picture
}

function pixelShuffle(img) {
  let pink = color(255, 102, 204);
  img.loadPixels();
  for (let i = 0; i < img.pixels.length; i += 16) {
    img.pixels[i] = red(pink);
    img.pixels[i + 1] = green(pink);
    img.pixels[i + 2] = blue(pink);
    img.pixels[i + 3] = alpha(pink);
  }
  img.updatePixels();
  return img;
}

EDITED 2x on July 9, 2021 to revise the supplied code.

Hello @javagar, thank you so much for your help!
I have pixelShuffle function here by modifying a random sort algorithm, but it doesn’t seem to be working (looks like it just returns the original image). If possible, could you look at this?

function pixelShuffle(pixels) {
  pixels.loadPixels();
  for(var i = (pixels.length - 1); 0 < i; i -= 4){

    var r = Math.floor(Math.random() * (i + 1));
    var arr1 = pixels.splice(r, 4);
    var arr2 = pixels.splice(i, 4);
    pixels = pixels.concat(arr1);
    Array.prototype.splice.apply(pixels, [r, 0].concat(arr2));
  }
  pixels.updatePixels();
  return pixels;
}
1 Like

Using pixels as the name for its parameter, your pixelShuffle function seems to confuse the distinction between the image and the p5.js pixels array.

Note, from p5.js: Reference: pixels, that pixels is a Uint8ClampedArray. For a description of the methods associated with that type, see MDN Web Docs: Uint8ClampedArray.

Try this example as an initial pattern for your script:

let capture;
let selected;
function setup() {
  createCanvas(400, 300);
  background(150);  
  // noLoop();
  capture = createCapture(VIDEO);
  capture.hide();
  selected = createImage(50, 50);
}

function draw() {
  image(capture, 0, 0);
  selected = capture.get(100, 100, 150, 150)
  selected = pixelShuffle(selected);
  image(selected, 50, 50);
}

function pixelShuffle(img) {
  img.loadPixels();
  
  // shuffle img.pixels, which is a Uint8ClampedArray
  shuffle(img.pixels, true);
  
  img.updatePixels();
  return img;
}

All the pixelShuffle function does in the above example is simply use the p5.js shuffle function to shuffle img.pixels randomly, which creates noise. However, the important thing is that it demonstrates that the function, as written, does return a changed image.

Beginning with that example, you can replace these lines in the pixelShuffle function with your own code for shuffling img.pixels:

  // shuffle img.pixels, which is a Uint8ClampedArray
  shuffle(img.pixels, true);

Be careful to only use methods on img.pixels that can be applied to the Uint8ClampedArray type.

EDITED on July 11, 2021 to add the following:

Since img.pixels is a Uint8ClampedArray, you will not be able to use the splice method on it, so you will need to find an alternative.

Below is an example of a pixelShuffle method that swaps portions of img.pixels, followed by a resulting image. You can adapt it to your needs by modifying the code.

function pixelShuffle(img) {
  
  img.loadPixels();
  
  // modify img.pixels, which is a Uint8ClampedArray
  let temp;
  for (i = 0; i < img.pixels.length / 2; i += 4) { 
    // compare the red components of the pixels
    if (img.pixels[i] > img.pixels[i + img.pixels.length / 2]) {
      // swap the red components
      temp = img.pixels[i];
      img.pixels[i] = img.pixels[i + img.pixels.length / 2];
      img.pixels[i + img.pixels.length / 2] = temp;
    }
  }
  
  img.updatePixels();
  return img;
}

img

2 Likes