Jordy van Look
Jordy van Look

Reputation: 63

How to crop an image in P5?

enter image description here

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.

The green line jitters around on purpose (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)

  }

}

Upvotes: 3

Views: 2953

Answers (1)

Kevin Workman
Kevin Workman

Reputation: 42176

The vertex() function you pointed out isn't cropping the image.

To crop an image, you probably want to use the PImage.mask() function. This lets you overlay a mask image overtop your original image so that only parts of your original image are visible.

You can also use a PGraphics instance as a mask image, so you can draw whatever mask you want. Here's a small example that creates a PGraphics mask consisting of an ellipse, then masks the original photo with that mask:

PImage photo;
PGraphics maskImage;

void setup() {
  size(100, 100);
  photo = loadImage("pic.jpg");
  maskImage = createGraphics(photo.width, photo.height);


  maskImage.beginDraw();
  maskImage.background(0);
  maskImage.fill(255);
  maskImage.ellipseMode(RADIUS);
  maskImage.ellipse(photo.width/2, photo.height/2, 500, 500);
  maskImage.endDraw();

  photo.mask(maskImage);
}

void draw() {
  background(255, 0, 0);
  image(photo, 0, 0, width, height);
}

Your sketch would use a shape instead of an ellipse, but those are the basics.

Upvotes: 2

Related Questions