Processing Making PImage with PGraphics - processing

I'm trying a simple masking of an image with a circle shape on top of it.
I don't understand why it is not working. The image gets printed correctly, but not a sing of a mask. This is my code:
PImage lion;
PGraphics mask;
void setup() {
size(720, 380);
lion = loadImage("lion.jpg");
mask = createGraphics(720, 380);
mask.beginDraw();
mask.ellipse(0, 0, 150, 150);
mask.fill(0, 0, 0);
mask.endDraw();
mask.mask(lion);
}
void draw() {
image(lion, 0, 0);
}
The lion image is just random image from google.

You have to apply the mask to the lion image and not to apply the lion image as a mask to the mask.
The first 2 parameters of the ellipse() are the x and y center coordinates of the ellipse.
Fill the entire mask with a black background and then draw a white ellipse to center of the mask:
void setup() {
size(720, 380);
lion = loadImage("lion.jpg");
int w = lion.width;
int h = lion.height;
mask = createGraphics(w, h);
mask.beginDraw();
mask.background(0);
mask.fill(255);
mask.ellipse(w/2, h/2, w, h);
mask.endDraw();
lion.mask(mask);
}
void draw() {
background(0);
image(lion, 0, 0);
}

Related

Processing P3D not rendering properly

I tried to make a simple 3d spinning cube in processing.
int size = 100;
float angle = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
lights();
translate(width/2, height/2, 0);
rotateY(angle);
rotateX(angle);
background(0);
box(size);
angle+=0.05;
}
When i run it, i got a nice spinning cube but there is some problem in rendering.
Found a similar thread with no answer:-
Processing P3D Animation leaving artifacts behind
Image Depicting the problem
Although I could not found the reason for this weird effect. But here is a quick hack which worked out for me.
Instead of using the background function to fill the background, simply draw a filled rectangle every frame.
int size = 100;
float angle = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
//black
fill(0);
//rectangle to fill the canvas
rect(0,0,width,height);
lights();
fill(255);
translate(width/2, height/2, 0);
rotateY(angle);
rotateX(angle);
box(size);
angle+=0.05;
}

How to create a mask from Polygons (processing)?

I am trying to create from a custom shape a mask for an image.
In processing I came up with this:
Image img;
PImage img2;
PGraphics mGraphic;
void setup(){
img = loadImage("mask.jpg");
img2 = loadImage("test.jpg");
mGraphic = createGraphics(1024,1024, JAVA2D);
size(img.width, img.height);
}
void draw(){
background(255);
mGraphic.beginDraw();
mGraphic.background(0);
mGraphic.ellipse(mouseX, mouseY, 400, 400);
mGraphic.endDraw();
img2.mask(mGraphic);
image(img2,0,0);
}
Above code will create a ellipse that will be the mask of the image.
I would like to achieve the same with a custom shape generated by Polygons:
import java.awt.Polygon;
PImage img;
PImage img2;
PGraphics mGraphic;
CustomShape myShape = new CustomShape();
void setup(){
img = loadImage("mask.jpg");
img2 = loadImage("test.jpg");
mGraphic = createGraphics(1024,1024, JAVA2D);
myShape.addPoint(25, 25);
myShape.addPoint(275, 25);
myShape.addPoint(275, 75);
myShape.addPoint(175, 75);
myShape.addPoint(175, 275);
myShape.addPoint(125, 275);
myShape.addPoint(125, 75);
myShape.addPoint(25, 75);
smooth();
// img2.filter(INVERT);
size(img.width, img.height);
}
void draw(){
background(255);
stroke(0);
myShape.display();
img2.mask(myShape);
image(img2,0,0);
}
class CustomShape extends Polygon {
void display() {
stroke(0);
fill(0);
beginShape();
for (int i=0; i<npoints; i++) {
vertex(xpoints[i], ypoints[i]);
}
endShape(CLOSE);
}
}
Unfortunately, this code will give me an error: The method mask(int[]) in the type PImage is not applicable for the arguments (Masking_image_1.CustomShape)
Is this even possible to get the same result as my first code, but then with the use of a custom shape? And how can I solve that?
If there are any questions left, please let me know. Above code will work inside Processing.
Well, your error says it all: the mask() function does not know what to do with a CustomShape parameter. The parameter needs to be a PImage or a mask array. More info can be found in the reference.
To use your custom shape, what you want to do is draw that custom shape to a PGraphics (which is a subclass of PImage), and then use that PGraphics as the mask. You'd do that using the createGraphics() function. Again, more info can be found in the reference.

How to detect only single color such as Red, Blue or Green from an image using Java or Processing?

I am working on a robotics project in which I have to some image processing in order to recognize blue colored objects, red colored obstacles, and green colored destination. I am using java for Image Processing.
Right now, I have been able to locate Red, Green, and Blue colored objects using Blobscanner library. But the difficulty is that, my algorithm only works fine when the background is pure Black. Because I am using RGB color model, and in RGB, black is represented as 0,0,0 and white as 255,255,255 and gray color also has some red component in it, so it also gets detected by the algorithm. I don't know the algorithm which exactly pinpoints the red color ignoring others.
Please help me detect only red color (and its other shades) in any image.
Well, while #geotheroy were posting I also gave this a try, it works and also is cool to see :) so I'm posting it anyway... Same base idea thought...
drag vertically to set the threshold, any key to view original.
PImage original, result;
float t = 0.9;
void setup() {
//image linked from this question in processing forum
//http://forum.processing.org/topic/help-random-distribution-of-non-overlapping-circles#25080000001787197
original = loadImage("http://24.media.tumblr.com/tumblr_lzi0y7OpsC1r87izio1_1280.png");
if (original != null) {
size(original.width, original.height);
result = createImage(original.width, original.height, RGB);
result = original.get(0, 0, original.width, original.height);
}
else
{
println("unable to load the image. Are you connected?");
exit();
}
}
void draw() {
if (keyPressed) {
image (original, 0, 0);
}
else {
image(result, 0, 0);
}
}
void mouseDragged() {
t = map(mouseY, 0, height, 0, 1);
findReds(original, t);
}
void findReds(PImage orig, float thresh) {
result = orig.get(0, 0, orig.width, orig.height);
result.loadPixels();
for (int i = 0; i < result.pixels.length; i++) {
color c = result.pixels[i];
float r = c >> 16 & 0xFF;
float g = c >> 8 & 0xFF;
float b = c & 0xFF;
float limitR = r - r*thresh;
if ( g < limitR && b < limitR) {
result.pixels[i] = color(255);
}
}
result.updatePixels();
}
Does this help give you some ideas:
PImage moog;
void setup() {
String url = "http://bananamondaes.files.wordpress.com/2013/02/the-moog.jpg";
moog = loadImage(url, "jpg");
size(moog.width, moog.height);
noStroke();
strokeWeight(10);
textSize(18);
textAlign(CENTER);
}
void draw() {
image(moog, 0, 0);
color c = moog.pixels[mouseY*width + mouseX];
fill(c);
ellipse(450,285,30,17);
ellipse(430,250,50,30);
ellipse(400,200,70,40);
ellipse(360,120,320,60);
fill(0);
text("Red: "+int(red(c))+", Green: "+int(green(c))+", Blue: "+int(blue(c)),360,125);
text("Check out Moog's ears..", 300, 50);
if(red(c)>200 & green(c)<100 & blue(c)<100) {
noFill();
stroke(c);
rect(5,5,width-10,height-10);
noStroke();
}
}

How to animate a 3D curve between two points on a map?

I am trying to do a twitter visualization.
I using curves to connect two points on the map.
Here is the code which I am using for it. It has been taken from an example by Chrisir from the processing forums.
void setup()
{
size( 800, 800, P3D );
} // setup
void draw()
{
// myCurveTest() ;
PVector firstpoint = new PVector (120, 320, -30);
PVector secondpoint = new PVector (320, 220, -30);
myCurve (firstpoint, secondpoint ) ;
firstpoint = new PVector (420, 220, 30);
secondpoint = new PVector (620, 120, -30);
myCurve (firstpoint, secondpoint ) ;
}
void myCurve (
PVector firstpoint,
PVector secondpoint) {
PVector beginningcontrolpoint = new PVector (120, firstpoint.y+1200, -30);
PVector endingcontrolpoint = new PVector (720, secondpoint.y+1200, -30);
myPointPVector(beginningcontrolpoint, color(255, 0, 0));
myPointPVector(firstpoint, color(0, 0, 255));
myPointPVector(secondpoint, color(0, 0, 255));
myPointPVector(endingcontrolpoint, color(255, 0, 0));
stroke (255);
noFill();
curve(
beginningcontrolpoint.x, beginningcontrolpoint.y, beginningcontrolpoint.z,
firstpoint.x, firstpoint.y, firstpoint.z,
secondpoint.x, secondpoint.y, secondpoint.z,
endingcontrolpoint.x, endingcontrolpoint.y, endingcontrolpoint.z);
}
void myPointPVector (PVector test, color col1) {
MyBox(test.x, test.y, test.z,
test.x+3, test.y, test.z,
9,
col1);
}
void MyBox(float x1, float y1, float z1, float x2, float y2, float z2, float weight, color strokeColour)
// was called drawLine; programmed by James Carruthers
// see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
{
PVector p1 = new PVector(x1, y1, z1);
PVector p2 = new PVector(x2, y2, z2);
PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
float rho = sqrt(pow(v1.x, 2)+pow(v1.y, 2)+pow(v1.z, 2));
float phi = acos(v1.z/rho);
float the = atan2(v1.y, v1.x);
v1.mult(0.5);
pushMatrix();
translate(x1, y1, z1);
translate(v1.x, v1.y, v1.z);
rotateZ(the);
rotateY(phi);
noStroke();
fill(strokeColour);
box(weight, weight, p1.dist(p2)*1.2);
popMatrix();
}
I want to animated this 3D curve so that I can see them being drawn on the map. Can anyone help me out with this. I have tried everything from framecount to advanced animation libraried in processing but no luck yet :(
Thanks.
You may just calculate a parabola point by point, draw it using curveVertex and orbit it in 3D using translate and rotate, here an example (using 1.5.1/P3D/fontMode(SCREEN)):
float initial_x = -200;
float x = initial_x;
float y;
float y_offset;
float r = 200;// change this to change the height of the parabola
ArrayList<PVector> pts = new ArrayList<PVector>();
float mx = 70, my = -15, tmx, tmy;
boolean animating = false;
PFont f;
void setup() {
size( 800, 400, P3D);
background(255);
smooth();
f = createFont("Arial", 15);
textMode(SCREEN);
}
void draw() {
//lights();
background(255);
fill(100);
textFont(f, 15);
text("drag to orbit", width - 10 - textWidth("drag to orbit"), height -30);
text("any key to redraw parabola", width - 10 - textWidth("any key to redraw parabola"), height -10);
//rotate 3d
translate(width/4, height/2);
rotateY(radians(mx));
rotateZ(radians(my));
// to mark origin and help view 3d
noFill();
stroke(100);
box(20);
pushMatrix();
translate(100, 5, -100);
stroke(200);
fill(0, 20);
box(600, 2, 600);
popMatrix();
//store y offset
if (x == initial_x) {
y_offset = (sq(x)+2*x)/r;
}
// stop parabola
if ( x == initial_x || x < -initial_x + 2) {
x+=2;
animating = true;
// add to curve storage
pts.add(new PVector(x, y));
}
else {
animating = false;
}
//calc y
y = (sq(x)+2*x)/r - y_offset;
stroke(50, 30, 7);
noFill();
strokeWeight(1);
//draw at origin
translate(-initial_x, 0);
//draw curve
beginShape();
for (PVector p:pts) {
curveVertex(p.x, p.y);
}
endShape();
//draw a ball
if (!animating) {
translate(pts.get(frameCount%pts.size()).x, pts.get(frameCount%pts.size()).y);
noStroke();
fill(220, 190, 35);
sphere(4);
}
}
void mousePressed() {
tmx = mouseX;
tmy = mouseY;
}
void mouseDragged() {
mx = tmx - mouseX;
my = tmy - mouseY;
}
void keyPressed() {
x = -200;
pts.clear();
}
You're drawing the curves using the curve() command (http://processing.org/reference/curve_.html) which draws a Catmull-Rom spline. In your code, you're only drawing a single spline section (the one between the two control points), so what you're really interested in is "how can I draw only part of a Catmull-Rom spline section". I don't have the answer for that one, but if you change your curve(control1, first, second, control2) call into a bezier(first,c1,c2,second) call (where you will now have to come up with the code for the control points c1 and c2) instead, then you can use de Casteljau's algorithm to cut up a curve into two segments anywhere along it. If you slide up the where-to-cut-it point every frame, and then only draw the first segment that you get from the split operation, it'll look like a curve that draws itself from the start to the end point. See http://pomax.github.io/bezierinfo/#splitting for the description on how to do this (bonus: the source code is even in Processing)
Make use of the curvePoint() method. Here is a resolution to a similar problem:
http://forum.processing.org/one/topic/animation-with-curve.html.

Processing: transparent image over curves

Im new to Processing. I would like to put a .jpg or .png over curves and ellipses, so that they can see only where the image is transparent.
My code is below. The problem with it is that the transparent area is not fully transparent, but transparent white and the not-transparent parts have also decreased opacity.
PImage img;
void setup() {
size(300,500);
frameRate(30);
strokeWeight(4);
img = loadImage("sziluettmeret.jpg");
}
void draw() {
background(0, 50, 70);
stroke(0,70,90);
noFill();
beginShape();
curveVertex(-100, -100);
curveVertex(10, 10);
curveVertex(250, 250);
curveVertex(300, 300);
endShape();
fill(255);
ellipse(20 ,20,15,15);
noFill();
tint(255, 100);
image(img, 0, 0);
}
UPDATE:
I have this in my code:
loadPixels();
for(int i=0; i < img.pixels.length; i++) {
tmpColor = img.pixels[i];
tmpRed = red(tmpColor);
tmpGreen = blue(tmpColor);
tmpBlue = green(tmpColor);
tmpAlpha = 255 - ((tmpRed + tmpGreen + tmpBlue)/3);
img.pixels[i] = color(2*tmpRed,tmpGreen/2,tmpBlue,0);
if(0xFFFFFF == tmpColor)
}
updatePixels();
The picture does not become transparent. (But it becomes purple, so the loop runs on every pixel for sure)
tint() doesn't do greenscreening. It'll recolor your image (if you use a non-neutral colour), and set the mix transparancy, so with tint(255,100), you effective gave the image an opacity of (approximately) 0.39
If you want to do greenscreening (or in your case, whitescreening), you want to run through the image's pixels when you load the image, then set opacity to 0 whenever r/g/b are 255, effectively "removing" all your white pixels.

Resources