A Processing class for dynamically cropping an image.
For Java, Android and ProcessingJS modes:
Snippet:
/***************************************************************************************** * * CROPPER CLASS * ****************************************************************************************/ public class Cropper { // START POSITION: CENTER OF THE SCREEN float x; float y; float xOffset = 0.0; float yOffset = 0.0; // MINIMUM SIZE OF THE CROP int minWidth; int minHeight; boolean locked = false; boolean enabled = false; /*************************************************************************************** * * CONSTRUCTOR * **************************************************************************************/ Cropper(float _x, float _y, int _minWidth, int _minHeight) { x = _x; y = _y; minWidth = _minWidth; minHeight = _minHeight; } // Cropper() /*************************************************************************************** * * DISPLAY THE CROPPING FRAME * **************************************************************************************/ void display() { pushStyle(); rectMode(RADIUS); strokeWeight(2); fill(255, 80); // IS ONE OF THE HANDLES BEING DRAGGED? boolean handleActive = false; // FIND THE ACTIVE HANDLE (=THE HANDLE BEING DRAGGED) AND MARK IT for (int i=0; i<4; i++) if (handles[i].locked) handleActive = true; if (handleActive) { // ONE OF THE HANDLES IS BEING DRAGGED stroke(255, 255, 0); } else { // CHANGE THE COLOR OF THE CROPPING FRAME, DEPENDING ON MOUSE OVER AND LOCKED STATE if (mouseOver()) { if (!locked) stroke(255, 0, 0); else stroke(0, 0, 255); } } // DISPLAY CROPPING FRAME rect(x, y, cropperSizeDiv2, cropperSizeDiv2); // DISPLAY HANDLES // UPPER LEFT handles[0].display(x-cropperSizeDiv2+handleSizeDiv2, y-cropperSizeDiv2+handleSizeDiv2); // UPPER RIGHT handles[1].display(x+cropperSizeDiv2-handleSizeDiv2, y-cropperSizeDiv2+handleSizeDiv2); // LOWER LEFT handles[2].display(x-cropperSizeDiv2+handleSizeDiv2, y+cropperSizeDiv2-handleSizeDiv2); // LOWER RIGHT handles[3].display(x+cropperSizeDiv2-handleSizeDiv2, y+cropperSizeDiv2-handleSizeDiv2); popStyle(); } // display() /*************************************************************************************** * * MOUSE IS BEING DRAGGED * **************************************************************************************/ void mouseDragged() { if (locked) { x = mouseX - xOffset; y = mouseY - yOffset; } } // mouseDragged() /*************************************************************************************** * * IS THE MOUSE OVER THE CROPPER? * **************************************************************************************/ boolean mouseOver() { return (mouseX > x-cropperSizeDiv2 && mouseX < x+cropperSizeDiv2 && mouseY > y-cropperSizeDiv2 && mouseY < y+cropperSizeDiv2); } // mouseOver() } // Cropper /***************************************************************************************** * * HANDLE CLASS: THE HANDLES FOR CHANGING THE SIZE OF THE CROP * ****************************************************************************************/ class Handle { float x, y; float xOffset = 0.0; float yOffset = 0.0; boolean locked = false; /*************************************************************************************** * * CONSTRUCTOR * **************************************************************************************/ Handle() { } // Handle() /*************************************************************************************** * * DISPLAY THE HANDLE * **************************************************************************************/ void display(float _x, float _y) { x = _x; y = _y; // IS ONE OF THE HANDLES BEING DRAGGED? boolean handleActive = false; for (int i=0; i<4; i++) { if (handles[i].locked) handleActive = true; } if (handleActive) // ONE OF THE HANDLES IS BEING DRAGGED: COLOR ALL HANDLES YELLOW fill(255, 255, 0); else fill(0, 0, 255); noStroke(); // DRAW HANDLE rect(x, y, handleSizeDiv2, handleSizeDiv2); } // display() /*************************************************************************************** * * HANDLE IS BEING DRAGGED * **************************************************************************************/ void mouseDragged(int nr) { if (locked) { // THIS IS THE ACTIVE HANDLE (BEING DRAGGED) if (nr==0 || nr==2) { // UPPER LEFT OR LOWER LEFT xOffset = pmouseX-mouseX; } else { // UPPER RIGHT OR LOWER RIGHT xOffset = mouseX-pmouseX; } if (nr==0 || nr==1) { // UPPER LEFT OR UPPER RIGHT yOffset = pmouseY-mouseY; } else { // LOWER LEFT OR LOWER RIGHT yOffset = mouseY-pmouseY; } x = mouseX; y = mouseY; cropperSizeDiv2 += xOffset; cropperSizeDiv2 += yOffset; // CONSTRAIN THE SIZE OF THE CROPPER if (cropperSizeDiv2 < thumbSizeDiv2) cropperSizeDiv2 = thumbSizeDiv2; if (cropperSizeDiv2 > (window.innerWidth>>1)) cropperSizeDiv2 = (window.innerWidth>>1); } // if (locked) } // mouseDragged() /*************************************************************************************** * * IS THE MOUSE OVER THIS HANDLE? * **************************************************************************************/ boolean mouseOver() { return (mouseX > x-handleSizeDiv2 && mouseX < x+handleSizeDiv2 && mouseY > y-handleSizeDiv2 && mouseY < y+handleSizeDiv2); } // mouseOver() } // Handle
Resources:
SjansMachine 4.0 (‘Selfie’-version)