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: (https://processing.org/reference/vertex_.html)

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.
      soundFormats('mp3');
      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
      frameRate(fr);

      // Add an event named drop, that runs function gotFile when a file is dropped onto the canvas
      c.drop(gotFile);

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

    };

    //------------------------------------------------------------------------------------------------

    function draw() {


      // Colour the background dark grey.
      background(200);

      // 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.
        paths[i].update();

        // Display each item in the array.
        paths[i].display();
      } 
      noStroke();
      noFill();
         beginShape();

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


    }


    //------------------------------------------------------------------------------------------------

    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(file.data).style("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) {
      //event.delta can be +1 or -1 depending
      //on the wheel/scroll direction
      print(event.delta);
      //move the square one pixel up or down
      pos += event.delta;
      //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++) {
        this.particles[i].update();
      }
    }

    // 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);
        strokeWeight(thickness);
        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()) {
        camera.play();
        save('myRemix.jpg');
        print(cropX);
        print(cropY)

      }

    }

Answers

  • 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.