Dragging png files in processing - java

I am trying to design something in processing for a university experiment. I need people to be able to drag images and place them on a map.
I was able to create the layout of my program and can load in the png files in a specific place within the window and I have place the map where I want in the window to.
I found some approach to dragging images and it was ok but it broke and was not efficient.
I came across the "dragging objects in processing" question on this website(found here: dragging objects in processing). Mike 'Pomax' Kamermans' code is really efficient and I was able to incorporate my current code with his so that I almost have what I want. The issue is that I am dragging stings. I have tried to adapt the code so that I can load in and drag images instead but it is beyond my level of knowledge. I do think that his approach to redrawing is the way to go. I also tried to find a method of replacing each string with an images but failed.
// adapted from Mike 'Pomax' Kamermans' code https://stackoverflow.com/questions/15305722/dragging-objects-in-processing
PImage wheel;
LineCollection lines;
float textSize;
void setup(){
size(displayWidth, displayHeight);
wheel = loadImage("wheel.png");
// fix the text size, reference a real font
textSize = 32;
textFont(createFont("Times New Roman", textSize));
// parse strings, construct Lines container
String[] textValues = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19"};
lines = new LineCollection(textValues);
// Do not loop! only update when events warrant,
// based on redraw() calls
noLoop();
}
// fall through drawing
void draw() {
background(255);
image(wheel, ((displayWidth/2) - ((displayWidth * 0.4167)/2)), 0, (displayWidth * 0.4167), (displayWidth * 0.4167));
stroke(0, 0, 0, 0);
fill(210, 210, 210);
rect(0, (displayHeight*0.75), displayWidth, displayHeight);
lines.draw();
}
// fall through event handling
void mouseMoved() { lines.mouseMoved(mouseX,mouseY); redraw(); }
void mousePressed() { lines.mousePressed(mouseX,mouseY); redraw(); }
void mouseDragged() { lines.mouseDragged(mouseX,mouseY); redraw(); }
void mouseReleased() { lines.mouseReleased(mouseX,mouseY); redraw(); }
/**
* A collection of lines. This is *only* a collecton,
* it is simply responsible for passing along events.
*/
class LineCollection {
Line[] lines;
int boundaryOverlap = 20;
// construct
LineCollection(String[] strings){
lines = new Line[strings.length];
int x, y;
for(int i=0, last=strings.length; i<last; i++) {
x = (int) (((displayWidth/20) * i) + 10);
y = (int) ((displayHeight*0.85)-10);
lines[i] = new Line(strings[i], x, y);
}
}
// fall through drawing
void draw() {
// since we don't care about counting elements
// in our "lines" container, we use the "foreach"
// version of the for loop. This is identical to
// "for(int i=0; i<lines.size(); i++) {
// Line l = lines[i];
// [... use l here ...]
// }"
// except we don't have to unpack our list manually.
for(Line l: lines) { l.draw(); }
}
// fall through event handling
void mouseMoved(int mx, int my) { for(Line l: lines) { l.mouseMoved(mx,my); }}
void mousePressed(int mx, int my) { for(Line l: lines) { l.mousePressed(mx,my); }}
void mouseDragged(int mx, int my) { for(Line l: lines) { l.mouseDragged(mx,my); }}
void mouseReleased(int mx, int my) { for(Line l: lines) { l.mouseReleased(mx,my); }}
}
/**
* Individual lines
*/
class Line {
String s;
float x, y, w, h;
boolean active;
color fillColor = 0;
int cx, cy, ox=0, oy=0;
public Line(String _s, int _x, int _y) {
s = _s;
x = _x;
y = _y;
w = textWidth(s);
h = textSize;
}
void draw() {
fill(fillColor);
text(s,ox+x,oy+y+h);
}
boolean over(int mx, int my) {
return (x <= mx && mx <= x+w && y <= my && my <= y+h);
}
// Mouse moved: is the cursor over this line?
// if so, change the fill color
void mouseMoved(int mx, int my) {
active = over(mx,my);
fillColor = (active ? color(155,155,0) : 0);
}
// Mouse pressed: are we active? then
// mark where we started clicking, so
// we can do offset computation on
// mouse dragging.
void mousePressed(int mx, int my) {
if(active) {
cx = mx;
cy = my;
ox = 0;
oy = 0;
}
}
// Mouse click-dragged: if we're active,
// change the draw offset, based on the
// distance between where we initially
// clicked, and where the mouse is now.
void mouseDragged(int mx, int my) {
if(active) {
ox = mx-cx;
oy = my-cy;
}
}
// Mouse released: if we're active,
// commit the offset to this line's
// position. Also, regardless of
// whether we're active, now we're not.
void mouseReleased(int mx, int my) {
if(active) {
x += mx-cx;
y += my-cy;
ox = 0;
oy = 0;
}
active = false;
}
}
Any help would be greatly appreciated.

The best advice I can give you is to stop trying to hamfist code you find on the internet into doing what you want. Even if the code is great, you need to understand what it's doing before you use it.
Take a step back and ask yourself how you would accomplish this yourself.
If all you want to do is drag a rectangular area (like an image), then you simply need to determine when the mouse is inside that area, then use the pmouseX and pmouseY variables to figure out how much to move that area. Something like this:
float squareX = 200;
float squareY = 200;
float squareWidth = 50;
float squareHeight = 50;
//keep track of when the mouse is inside the square
boolean mouseInSquare = false;
void setup() {
size(500, 500);
}
//check if the mouse is in the square
void mousePressed() {
if (mouseX > squareX && mouseX < squareX + squareWidth && mouseY > squareY && mouseY < squareY + squareHeight) {
mouseInSquare = true;
}
}
//if the mouse is in the square, then move it when the mouse is dragged
void mouseDragged() {
if (mouseInSquare) {
float deltaX = mouseX - pmouseX;
float deltaY = mouseY - pmouseY;
squareX += deltaX;
squareY += deltaY;
}
}
//when we let go of the mouse, stop dragging the square
void mouseReleased() {
mouseInSquare = false;
}
//draw the square
void draw() {
background(0);
rect(squareX, squareY, squareWidth, squareHeight);
}

Related

How to make an object appears with mousePress and stay on the screen?

(new to java). So I am have created the following script and I would like my object called "site" to appear only when the mouse is pressed and then stay on the screen. Then at every mouse pressed it created a new "site".
What it does now is that it creates a site at the beginning and the adds one when the mouse is pressed. But I don't want that site in the beginning, I just want it when I click.
Is anyone could help me that would be great!
/*preload = "factory_12.png";*/
/*preload = "sign.png";*/
/*preload = "simple_truck.png";*/
Lorry lorry;
PImage concretePlant;
PFont aFont;
int xCoord;
int yCoord;
ArrayList<Site> sites;
int siteSize = 30;
void setup() // What is called once at the beginning
{
size (500, 500);
concretePlant = loadImage("factory_12.png");
aFont = createFont("IndustrialRevolution-Regular", 12);
textFont(aFont);
xCoord = int(width/2);
yCoord = int(height/2);
//Creating empty Array List where store sites objects
sites = new ArrayList<Site>();
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
//storing lorries
lorry = new Lorry(xCoord, yCoord);
}
void draw() // Draw the background and concrete plant
{
background (235, 247, 255); //light blue background, not in draw as it wouldn't allow the site image to stay
image(concretePlant, xCoord, yCoord, 60, 60);
fill(1);
text("Concrete Plant", xCoord-20, yCoord+70);
//Calling the sites
for (int i = sites.size () - 1; i>=0; i--) {
Site site = sites.get(i);
site.displaySites();
}
//calling the lorry functions
lorry.updateLorry();
}
void mousePressed() {
sites.add(new Site(mouseX, mouseY, siteSize));
}
class Site
{
float x,y;
float size;
PImage picture;
Site (float xin, float yin, float sin)
{
x = xin;
y = yin;
size = sin;
picture = loadImage("sign.png");
}
void displaySites()
{
image(picture, x, y, 60, 60);
}
}
class Lorry
{
PVector location;
PVector concretePlant;
PVector velocity;
PImage mixer;
boolean changeDirection;
int siteNumber = 0;
Site destination;
Lorry(float xCoord, float yCoord)
{
concretePlant = new PVector(xCoord, yCoord); //Initial start point
location = new PVector(xCoord, yCoord); //Initial start point
velocity = new PVector(2, 2);
mixer = loadImage("simple_truck.png");
destination = sites.get(siteNumber);
changeDirection = false;
}
void displayLorry()
{
image(mixer, location.x, location.y, 30, 30);
}
void Move()
{
float xdir = destination.x - location.x;
float ydir = destination.y - location.y;
PVector dir = new PVector (xdir, ydir);
dir.normalize();
location.add(dir);
print("going");
}
void reachDestination()
{
//println(destination,location);
//if ((destination.x == location.x) && (destination.y == location.y)) {
if (dist(destination.x, destination.y, location.x, location.y) < 1) {
if (siteNumber <sites.size() -1) {
siteNumber++; // siteNumber = siteNumber + 1;
destination = sites.get(siteNumber);
changeDirection = true;
} else {
println("reached final site");
}
println("reachedDestination");
}
}
void updateLorry()
{
displayLorry();
Move();
reachDestination();
}
}
Thank you :)
Get rid of this line:
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
This line in your setup() function adds a Site. If you don't want to add a Site at startup, remove this line.
You should also try to go through the process of debugging your problem. For example, step through the code line-by-line with a piece of paper and a pencil, or add print statements, or use the debugger that comes with the Processing editor. That will help you figure out problems like this in the future. Good luck!

How to update a canvas in SWT every 100 milliseconds inside a KeyListener Java

I'm writing a program which updates a canvas after every key press by regenerating a data structure (cube) and then painting this onto the canvas. If the user enters 'S' I want the canvas to display the cube after every turn (turn = one character of the solution string generated by the program) every 100ms and redraw this to the screen, have tried several different approaches but can't get it to work. This is my KeyListener code:
canvas.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
GC gc = new GC(canvas);
Rectangle rect = canvas.getClientArea();
String alg = ""+e.character;
cube.performAlgorithm(alg, false);
drawCube(rect,gc);
if(e.character=='S'){
Cube cube2 = new Cube(cube);
String solution = Solutions.longsolve(cube2, "Fridrich", false);
String[] moves = new String[solution.length()];
moves = solution.split("(?!^)");
for(String move : moves){
cube.performAlgorithm(move, false);
try {
drawCube(rect,gc);
canvas.redraw();
canvas.update();
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
//System.out.println(solution);
}
gc.dispose();
}
});
and my drawFace and drawCube code, appreciate this may not be a very nice way of solving my problem but I'm very new to using SWT.
private static void drawFace(GC gc, int startwidth, int startdepth, int celldim, Color[] colour, byte[][] Face){
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
int x = startwidth;
int y = startdepth;
//draw face of the cube
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
Rectangle rect = new Rectangle(x, y, celldim, celldim);
gc.setBackground(colour[Face[i][j]]);
gc.fillRectangle(rect);
gc.drawRectangle(rect);
x += celldim;
//only draw a box
}
x = startwidth;
y+=celldim;
}
}
private static void drawCube(Rectangle clientArea, GC gc){
int startdepth = 10;
int celldim = (((clientArea.height)-(startdepth*2))/12);
int startwidth = (int) ((int)(clientArea.width/2)-(1.5*celldim));
Color[] colours = {gc.getDevice().getSystemColor(SWT.COLOR_GREEN),gc.getDevice().getSystemColor(SWT.COLOR_RED),
gc.getDevice().getSystemColor(SWT.COLOR_BLUE),gc.getDevice().getSystemColor(SWT.COLOR_GRAY),
gc.getDevice().getSystemColor(SWT.COLOR_BLACK),gc.getDevice().getSystemColor(SWT.COLOR_YELLOW)};
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
int x = startwidth;
int y = startdepth;
drawFace(gc, x, y, celldim,colours,cube.Uface);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Fface);
x -= (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Lface);
x += (6*celldim);
drawFace(gc, x, y, celldim,colours,cube.Rface);
x -= (3*celldim);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Dface);
y += (3*celldim);
drawFace(gc, x, y, celldim,colours,cube.Bface);
}
You can't do updates in a loop like that because you must let the main SWT Display.readAndDispatch loop run since this is what actually updates the screen.
Instead use Display.timerExec to execute one step of the loop every 100ms:
Display.getDefault().timerExec(100, new Runnable() {
#Override
public void run() {
canvas.redraw();
// Run again - TODO add logic to stop after correct number of moves
Display.getDefault().timerExec(100, this);
}
});
You should just call redraw in this routine, all the actual drawing should be in a paint listener on the control.

Calculating the accumulated area of an array of shapes

I am trying to calculate the accumulating area for every creation of a rectangle.
I am aware of how to calculate the area for every time I create a rectangle, but I was hoping to get a running total.
Thanks!
float[] p1x = new float[0]; // hold the mouse pressed marks
float[] p1y = new float[0];
float[] p1z = new float[0];
float[] p2x = new float[0]; // hold the mouse pressed marks
float[] p2y = new float[0];
float[] p2z = new float[0];
int count = 0;
int rect_x1; // catch the start dragging point x
int rect_y1; // catch the start dragging point y
int rect_x2; // record moving mouseX
int rect_y2; // record moving mouseY
int rect_z1; // record mouseX releasing point
int rect_z2; // record mouseY releasing point.
boolean press, release, drag, drawRect;
void setup() {
smooth();
size(600, 400);
stroke(255);
fill(255, 255, 255, 10);
}
void draw() {
background(50);
Rect();
}
void Rect() {
float sizex = rect_x2 - rect_x1;
float sizey = rect_y2 - rect_y1;
for (int i = 0; i < count; i++) {
beginShape();
vertex(p1x[i], p1y[i]);
vertex(p2x[i], p1y[i]);
vertex(p2x[i], p2y[i]);
vertex(p1x[i], p2y[i]);
endShape(CLOSE);
}
if (mousePressed && mouseButton == LEFT) {
rect(rect_x1, rect_y1, sizex, sizey);
}
}
void mousePressed() {
p1x = append(p1x, mouseX);
p1y = append(p1y, mouseY);
rect_x1 = mouseX;
rect_y1 = mouseY;
mouseDragged(); // Reset vars
}
void mouseReleased() {
p2x = append(p2x, mouseX);
p2y = append(p2y, mouseY);
rect_x2 = mouseX;
rect_y2 = mouseY;
count++;
}
void mouseDragged() {
rect_x2 = mouseX;
rect_y2 = mouseY;
}
Well, you've got a couple options.
Option 1: Calculate the total every time you draw the rectangles. You've got a for loop in your Rect() function that loops through and draws them. You can just calculate the total area then.
Option 2: Keep a running total, and increment that every time you add a rectangle. You can do this in your mouseReleased() function.
I'm not sure exactly what you mean when you say you want one single accumulated number. You either have to total them up whenever you want the total, or you need to keep a running total and add to it whenever you add a new rectangle.

How to find the corner pixels of a rectangle?

Given a simple monochrome bitmap that contains a single, randomly rotated rectangle. How can I find the left/top, left/bottom, right/bottom and right/top corner positions of the rectangle inside the bitmap?
For example, this is how the bitmap could look like, where the X marks the pixels in question:
......... ......... ......... .........
.X11111X. ....X.... ..X11.... ....11X..
.1111111. ...111... ..11111X. X111111..
.1111111. ..X111X.. ..111111. .111111..
.X11111X. ...111... .1111111. .1111111.
......... ....X.... .111111.. ..111111.
......... ......... .X11111.. ..11111X.
......... ......... ....11X.. ..X11....
......... ......... ......... .........
Please excuse the bad ascii art.
For the second example, the corner pixel at the top could either be the rectangles left/top or right/top corner. Either is fine.
What steps are required to determine the corner pixels/positions in the above examples?
The corner pixels are the pixels the furthest apart. Find the top most row and the bottom most row. There will always be a corner pixel in those.
The corner pixel can only be the first or last pixel in this the topmost row row (or both if there's just the one).
So compare the distances between the first pixel in the topmost row and the last pixel in the bottom most row. And last pixel in topmost with the first in bottom most. The corners there are the the ones that are the furthest apart.
Since they are all the same distance in the Y you need the pixels with the greatest difference with regard to their x location. The corners are the pixels for which abs(x0-x1) is the greatest, where x0 is in the topmost row and x1 is in the bottom most.
Repeat this for the rightmost and leftmost rows.
If the topmost corner is on the left then the leftmost corner is on the bottom, the bottom most corner is on the right and the rightmost corner is on the top. Once you have the top, bottom, left, and right rows there's really just the two possibilities that can be solved in an if statement. But, due to the edge condition of having one pixel on the topmost row and two on the rightmost row, you're better off just running the algorithm again with transposed x and ys to solve for the other two corners rather than trying to spare yourself an if statement.
Not every monochrome bitmap is going to give you an answer. A complete algorithm needs an output that says "Unique corners not present". The following figures give an example of the problem:
......... ......... ..........
...XX.... ....X.... ....XX....
..X11X... ...111... ...1111...
..X11X... ..X111X.. ..X1111X..
...XX.... ...111... ..X1111X..
......... ....X.... ...X11X...
......... ......... ....XX....
......... ......... ..........
The degeneracy illustrated happens when the slopes of the rectangle are +1 and -1 and the position of the center is half-integral . It can also occur with other combinations of slopes and positions. The general answer will need to contain pixel-pairs as the best approximation of a vertex.
Start with the bounding box of the rectangle.
For each corner, move it clockwise until there is a black square.
public class Test {
String[][] squares = {
{
".........",
".X11111X.",
".1111111.",
".1111111.",
".X11111X.",
".........",
".........",
".........",
".........",},
{
".........",
"....X....",
"...111...",
"..X111X..",
"...111...",
"....X....",
".........",
".........",
".........",},
{
".........",
"..X11....",
"..11111X.",
"..111111.",
".1111111.",
".111111..",
".X11111..",
"....11X..",
".........",},
{
".........",
"....11X..",
"X111111..",
".111111..",
".1111111.",
"..111111.",
"..11111X.",
"..X11....",
".........",}};
private static final int WHITE = 0;
private static final int BLACK = 1;
class Point {
private final int x;
private final int y;
public Point(Point p) {
this.x = p.x;
this.y = p.y;
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public String toString() {
return "{" + x + "," + y + '}';
}
// What colour is there?
public int colour(int[][] bmp) {
// Make everything off-bmp black.
if (x < 0 || y < 0 || y >= bmp.length || x >= bmp[y].length) {
return BLACK;
}
return bmp[y][x];
}
private Point step(Point d) {
return new Point(x + d.x, y + d.y);
}
}
class Rectangle {
private final Point[] corners = new Point[4];
public Rectangle(Point[] corners) {
// Points are immutable but corners are not.
System.arraycopy(corners, 0, this.corners, 0, corners.length);
}
public Rectangle(Rectangle r) {
this(r.corners());
}
public Rectangle(Point a, Point b, Point c, Point d) {
corners[0] = a;
corners[1] = b;
corners[2] = c;
corners[3] = d;
}
private Rectangle(Point tl, Point br) {
this(tl, new Point(br.x, tl.y), br, new Point(tl.x, br.y));
}
public Point[] corners() {
return Arrays.copyOf(corners, corners.length);
}
#Override
public String toString() {
return Arrays.toString(corners);
}
}
private Rectangle getBoundingBox(int[][] bmp) {
int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = 0, maxY = 0;
for (int r = 0; r < bmp.length; r++) {
for (int c = 0; c < bmp[r].length; c++) {
if (bmp[r][c] != WHITE) {
if (minX > c) {
minX = c;
}
if (minY > r) {
minY = r;
}
if (maxX < c) {
maxX = c;
}
if (maxY < r) {
maxY = r;
}
}
}
}
return new Rectangle(new Point(minX, minY), new Point(maxX, maxY));
}
Point[] clockwise = new Point[]{
new Point(1, 0),
new Point(0, 1),
new Point(-1, 0),
new Point(0, -1)};
private void test(int[][] bmp) {
// Find the bounding box.
Rectangle bBox = getBoundingBox(bmp);
System.out.println("bbox = " + bBox);
Point[] corners = bBox.corners();
// Move each corner clockwise until it is black.
for (int p = 0; p < corners.length; p++) {
while (corners[p].colour(bmp) == WHITE) {
corners[p] = corners[p].step(clockwise[p]);
}
}
System.out.println("rect = " + new Rectangle(corners));
}
private void test(String[] square) {
// Build the int[][].
// . -> White
// X/1 -> Black
int[][] bmp = new int[square.length][];
for (int r = 0; r < square.length; r++) {
bmp[r] = new int[square[r].length()];
for (int c = 0; c < bmp[r].length; c++) {
switch (square[r].charAt(c)) {
case '.':
bmp[r][c] = WHITE;
break;
case 'X':
case '1':
bmp[r][c] = BLACK;
break;
}
}
}
test(bmp);
}
public void test() {
for (String[] square : squares) {
test(square);
}
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
prints
bbox = [{1,1}, {7,1}, {7,4}, {1,4}]
rect = [{1,1}, {7,1}, {7,4}, {1,4}]
bbox = [{2,1}, {6,1}, {6,5}, {2,5}]
rect = [{4,1}, {6,3}, {4,5}, {2,3}]
bbox = [{1,1}, {7,1}, {7,7}, {1,7}]
rect = [{2,1}, {7,2}, {6,7}, {1,6}]
bbox = [{0,1}, {7,1}, {7,7}, {0,7}]
rect = [{4,1}, {7,4}, {4,7}, {0,2}]
Could be improved by looking for a run of black and choosing the middle of the run.
Scan the image from the top, row by row until you find a black run.
Repeat four ways, from the bottom up, left, right, giving you eight corner candidates.
Take the run endpoints the farthest apart in the top and bottom rows. This tells you which endpoints to take vertically.

Combining two codes with a mousePressed-event processing

My problem is following:
I wrote a code and managed to display an image when i click on a rectangle (with the loadImage-fuction). The rectangle serves as a button that I want to replace with an image later.
But i actually don't just want an image to be displayed when the button is clicked. I want to call a code, to copy an image onto another:
public static int SQUARE_WIDTH = 30;
public static int SQUARE_HEIGHT = 30;
PImage img1,img2, img3;
void setup() {
size(670, 943);
img1 = loadImage("white.png");
img2 = loadImage("hase.jpg");
img3= loadImage("ohrring.jpg");
image(img1,0,0);
}
void draw() {
if(mousePressed)
copy(img2,
constrain(mouseX-SQUARE_WIDTH/2,0,width),
constrain(mouseY-SQUARE_HEIGHT/2,0,height),
SQUARE_WIDTH,SQUARE_HEIGHT,
constrain(mouseX-SQUARE_WIDTH/2,0,width),
constrain(mouseY-SQUARE_HEIGHT/2,0,height),
SQUARE_WIDTH,SQUARE_HEIGHT);
}
The copy-code doesn't simply copy an image, it uses the mouse as a brush! When you "draw" on an area, the image shows with the "strokes" of the brush pixel after pixel!
processing.org/reference/copy_.html
I happen to have huge problems when I want to combine this one with my main code:
int rectX, rectY;
int rectSize = 90;
boolean rectOver = false;
color rectHighlight;
color currentColor, baseColor;
color rectColor;
public static int SQUARE_WIDTH = 30;
public static int SQUARE_HEIGHT = 30;
PImage img1,img2, img3;
void setup() {
size(670, 943);
rectColor = color(0);
rectX = width/2-rectSize-10;
rectY = height/2-rectSize/2;
baseColor = color(102);
currentColor = baseColor;
img1 = loadImage("frida.jpg");
img2 = loadImage("hase.jpg");
img3 = loadImage("white.png");
background(img3);
}
void draw() {
update(mouseX, mouseY);
if (rectOver) {
fill(rectHighlight);
} else {
fill(rectColor);
}
stroke(255);
rect(rectX, rectY, rectSize, rectSize);
}
void update(int x, int y) {
if ( overRect(rectX, rectY, rectSize, rectSize) ) {
rectOver = true;
}else {
rectOver = false;
}
}
void mousePressed() {
if (rectOver) {
background(img2);
}
}
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}
Theoretically I got the tip to set a boolean in mousePressed() to do the copy-operation in draw(), and then to check this boolean in draw(): if set (true) it shall do the copy. But I'm unfortunately not the brightest star in the programming-sky , so could anybody show me what this part is supposed to look like? Of course, I'm open to other suggestions how to solve this problem!
Thank you!
I hope this is what you are looking for. If you want to copy an image you don't need to call a function to copy an image, you can simply invoke the = sign and the image will be copied.
In my example code buttonImage is the image on the button. Whenever you don't want an image on the button assign it the following way:
buttonImage = null;
If you want to have an image instead of the rectangle do the following:
buttonImage = yourImage;
buttonImage.resize(w, h); //fit it on the button.
I think this is what you want to achieve?
PImage buttonImage;
void setup()
{
}
void draw()
{
if(buttonImage == null || buttonImage.width < 2) rect(x, y, w, h);
else image(buttonImage, x, y);
}
void mouseReleased()
{
if(mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h)
{
//copy any image onto the buttonImage
buttonImage = loadImage("newPath.png"); //update / overwrite image
buttonImage.resize(w, h); //fit it on the button
}
}
x and y are the position of the button, w and h are the width and the height of the button in my example.
EDIT:
Ok, so basically you want to have a white background and you want to scrap it using your tool so an image appears? I'm still not 100% sure of what you're asking, but if that is the case try this:
I used img.get() instead of img.copy(), because it has less parameters to deal with. I really hoped i understood this correctly, if not maybe link a video to something similar? I have a hard time understanding what you want.
The toolSelected integer is a counter to which tool you are using. Depending on its value, it is executing a different code.
My code:
PImage img1;
int toolSelected = 0; //Normal tool;
int widthOfBrush = 20; //Now you are drawing 20x20
int buttonX = 200;
int buttonY = 200;
int buttonW = 40;
int buttonH = 20;
void setup()
{
size(640, 480);
background(255);
img1 = loadImage("yourImg.png");
img1.resize(width, height); //Fit it on processing screen
}
void draw()
{
if(toolSelected == 0) {}//other tool
//Instead of using copy we will be using buttonImage.get(x, y, w, h) --> makes more sense
if(toolSelected == 1 && mousePressed)
{
float yourX = mouseX;
float yourY = mouseY;
yourX -= floor(widthOfBrush / 2);
yourY -= floor(widthOfBrush / 2);
//scale & copy:
PImage brushImage = img1.get((int)yourX, (int)yourY, widthOfBrush * (width / img1.width), widthOfBrush * (width / img1.width)); //Draw the image at your destination
image(brushImage, mouseX, mouseY);
}
stroke(0);
fill(255);
rect(buttonX, buttonY, buttonW, buttonH);
}
void mouseReleased()
{
if (mouseX > buttonX && mouseX < buttonX + buttonW && mouseY > buttonY && mouseY < buttonY + buttonH)
{
//copy any image onto the buttonImage
//buttonImage = loadImage("newPath.png"); //update / overwrite image
toolSelected = 1; //Our tool is the image brush now.
}
}

Categories

Resources