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)