How to crop an image in P5?

edited December 2015 in p5.js Library Questions

I am working on a program in P5, an offshoot of Processing, that allows the user to upload an image, draw a line on top of the image, and then crop everything outside of the drawn shape out of the image.

Screen Shot 2015-12-23 at 11.30.32 Screen Shot 2015-12-23 at 11.27.21 (The green line jitters around on purpose)

I managed to get the points of the drawn line into an array, as well as make a shape out of these points. However, the cropping of the image is still a problem.

Processing has this functionality in vertex: (

However, I don't believe P5 has this functionality. I really don't want to have to convert the entire sketch into Processing. Is there any way to do this in P5, or to quickly convert this sketch into processing?

    // Make a variable to store the start image, as well as the drop image.
    var img;

    var cropX = [];
    var cropY = [];
    var pos = 25;
    // Make an array for all paths.
    var paths = [];

    // Make a bool for whether or not I am painting.
    var painting = false;

    // Int for how long until drawing the next circle
    var next = 10;

    // Make vars for vectors that determine where the line is drawn.
    var current;
    var previous;

    // Make ints for how much the lines dance around.
    var shake = 10;
    var minShake = shake * -1;
    var maxShake = shake * 1;

    // Make an int for the line thickness.
    var thickness = 2;
    var camera;
    var tracing = false;

    // Make vars to store the random values for colours into. 
    var rc1;
    var rc2;
    var rc3;

    // Variable for the framerate.
    var fr;

    // Variable that disables drawing lines when you didn't upload an image yet.
    var tracing = false;


    function preload() {

      //Load the starting image, and store it in img.
      img = loadImage("assets/startscreen.png");

      //Load the sound that plays when you export a screenshot.
      camera = loadSound('assets/camera.mp3');



    function setup() {

      // Set the framerate so the lines don't jump about too quickly.
      fr = 20;

      // Setup a canvas
      var c = createCanvas(1680, 1050);

      // Store a random value out of 255 into the random colour values.
      rc1 = random(255);
      rc2 = random(255);
      rc3 = random(255);

      // Apply the right framerate

      // Add an event named drop, that runs function gotFile when a file is dropped onto the canvas

      // Store 0,0 vectors in current and previous.
      current = createVector(0, 0);
      previous = createVector(0, 0);



    function draw() {

      // Colour the background dark grey.

      // Draw the loaded image at 0,0 coordinates.
    image(img, 0, 0);


      // Count if I've been painting for longer than the 'next' variable.
      // Also check if tracing is enabled (if I've dropped an image or not).
      // If these are true I can draw a new line.
      if (millis() > next && painting && tracing) {

        // Grab mouse position and store it in variables mouseX and mouseY.  
        current.x = mouseX;
        current.y = mouseY;

        // Add new particle
        paths[paths.length - 1].add(current);

        // Update the 'next' variable, to allow itself 200 extra millisecond for drawing the actual line.
        next = millis() + 200;

        // Move the mouse values used to draw the end of the line
        // to a variable used to draw the start of the line,
        // so that the line is continuous.
        previous.x = current.x;
        previous.y = current.y;
        append(cropX, current.x);
        append(cropY, current.y);

      // Make an integer called i, with a value of 0.
      // Add 1 to i for each item in the array paths.

      // Run this once for each item in the array.
      // Name each item in the array 'i' while working.
      // Display each item in the array.
      for (var i = 0; i < paths.length; i++) {

        // Update the current object in the array.

        // Display each item in the array.

         for (var i = 0; i < cropX.length; ++i) {
           vertex(cropX[i], cropY[i]);



    var ready = false;

    // Make a function called gotFile, using the variable file.
    function gotFile(file) {

      // Check if the dropped file is an image file
      if (file.type === 'image') {

        // Enable drawing lines.
        tracing = true;

        // if (ready) {
        //   img.remove();
        // }
        // Store the dropped image in the container which used to hold the startimage.
        img = createImg("opacity: 100; position: absolute; top: -10; right: -10; z-index: 100;draggable=false;");

        ready = true;

        // Error message in case not an image file.
      } else {
        println('Not an image file!');


    function mouseWheel(event) {
      // can be +1 or -1 depending
      //on the wheel/scroll direction
      //move the square one pixel up or down
      pos +=;
      //uncomment to block page scrolling
      return false;

    function mouseDragged() {
    return false;

    // If left mousebutton is pressed down,
    function mousePressed() {
      if (mouseButton == LEFT) {

        // set the variable counting when to place a new line to 0,
        next = 0;

        // set painting to true,
        painting = true;

        // store the mouse coordinates in mouseX and mouseY,
        previous.x = mouseX;
        previous.y = mouseY;

        // and add a new Path method to the array.
        paths.push(new Path());

    // When mouse is released, set painting to false, which disables any paths being drawn.
    function mouseReleased() {
      painting = false;


    // Describe the Path function that should be pushed to the array.
    function Path() {

      // Create an array inside this function named particles.
      this.particles = [];

    // Add the variable position to the function Path as its function'()' variable.
    Path.prototype.add = function(position) {

      // Add a new particle to this particle array with a position and hue.
      this.particles.push(new Particle(position, this.hue));

    // Take the Path() function, and and add this command to it.
    Path.prototype.update = function() {

      // Make an integer called i, with a value of 0.
      // Add 1 to i for each item in the array paths.

      // Run this once for each item in the array.
      // Name each item in the array 'i' while working.
      // Display each item in the array.
      for (var i = 0; i < this.particles.length; i++) {

    // Display the Path array.
    Path.prototype.display = function() {

      // Loop through the array of particles backwards.
      for (var i = this.particles.length - 1; i >= 0; i--) {

        // Display each of these particles.
        this.particles[i].display(this.particles[i + 1]);



    // Particles along the path
    function Particle(position, hue) {

      // Set the position of Particles to the mouseposition by creating a vector.
      this.position = createVector(position.x, position.y);

    // Constantly update Particle.
    Particle.prototype.update = function() {}

    // Draw particle and connect it with a line
    // Draw a line to another
    Particle.prototype.display = function(other) {
      stroke(255, 255);

      // If we need to draw a line
      if (other) {
        stroke(rc1, rc2, rc3);
        line(this.position.x + random(minShake, maxShake), this.position.y + random(minShake, maxShake), other.position.x + random(minShake, maxShake), other.position.y + random(minShake, maxShake));
      if (keyIsDown(LEFT_ARROW) && !camera.isPlaying()) {;




  • Looks like you actually want to apply the image as a texture to a vertex based shape. It's not clear from the p5js reference that this is available (yet). A possible workaround would involve drawing the vertex shape to a buffer image and using that as a mask on the image...

Sign In or Register to comment.