Then that's not cropping, that's masking. There are lot of topics on mask() and friends.
[EDIT] For the record, it was indeed cropping, because the wanted result must have exactly the size of the circle (masking makes the pixels outside the masked area transparent, it doesn't remove them). I misunderstood the question.
... how i can do the same thing with a image and copy what is inside the circle.
Just createImage(), then copy every pixel from the original PImage which is within the radius area!
Take a look at eraseCanvas() function there. And adapt it to copy the selected pixels within radius!
@GoToLoop thanks!! i try to do it but i ran into some problems.i try to do it but i have a bug:"syntax error maybe missing a semicolon", i dont undrstand why?...
i try to do 2 things :
1.when i'm clicking with the left mouse i need to copy the pixels that are inside the circle to a new image and draw it to the (0,0) pixels.
2.when i'm clicking with the left mouse i need to blur the pixels that are inside the circle.
i'll really appreciate your help!! i dont know how to resolve it..
this your example code that i try to use with some change of my:
PGraphics canvas;
PImage bg;
PImage flower;// the image that i try to do the changes
int diam = 50;
void setup() {
size(640, 360);
frameRate(50);
noLoop();
noFill();
flower=loadImage("flower.jpg");
canvas = createGraphics(width, height);
canvas.beginDraw();
canvas.smooth();
canvas.strokeWeight(diam);
canvas.endDraw();
bg = createBG(0150);
mouseX = width >> 1;
mouseY = height >> 1;
mouseButton = CENTER;
mousePressed();
}
void draw() {
background(flower);
image(canvas, 0, 0);
canvas.image(flower,0,0);
ellipse(mouseX, mouseY, diam, diam);
}
void keyPressed() {
canvas.clear();
canvas.endDraw();
redraw();
}
void mousePressed() {
if (mouseButton != CENTER) return;
final color c = (color) random(#000000);
stroke(c);
canvas.stroke(c);
canvas.endDraw();
if (mouseButton == LEFT) eraseCanvas();
redraw();
}
void mouseMoved() {
redraw();
}
/*void mouseDragged() {
if (mouseX < 0 | mouseX >= width
| mouseY < 0 | mouseY >= height) return;
if (mouseButton == LEFT) drawCanvas();
else eraseCanvas();
redraw();
}*/
void mouseWheel(MouseEvent me) {
final int inc = keyPressed & keyCode == CONTROL ? -1 : -5;
diam = constrain(diam + me.getCount()*inc, 1, 100);
canvas.strokeWeight(diam);
canvas.endDraw();
redraw();
}
/*void drawCanvas() {
canvas.line(mouseX, mouseY, pmouseX, pmouseY);
canvas.endDraw();
}*/
void eraseCanvas() {
final int cp[] = canvas.pixels, cw = canvas.width;
final int rad = diam>>1, radSq = rad*rad;
final int mx = mouseX, my = mouseY;
PImage des= createImage(50, 50, RGB);
des.loadPixels();
final int xStart, yStart, xEnd, yEnd;
xStart = max(mx - rad, 0);
xEnd = min(mx + rad, cw);
yStart = max(my - rad, 0);
yEnd = min(my + rad, canvas.height);
/*
for (int x = xStart; x != xEnd; x++)
for (int y = yStart; y != yEnd; y++)
if (sq(mx - x) + sq(my - y) <= radSq) cp[x + y*cw] = 0;
*/
for (int y = yStart; y != yEnd; y++) {
final float myySq = sq(my - y);
for (int cwy = cw*y,x = xStart, i=0 ; x != xEnd, i < des.pixels.length; x++, ,i++)
if (sq(mx - x) + myySq <= radSq) cp[cwy + x] = des.pixels[i];
}
canvas.updatePixels();
des.updatePixels();
image(des,0,0);
}
PImage createBG(int div) {
int i = div = constrain(div, 1, 0400);
final PGraphics pg = createGraphics(width, height);
final int wdiv = width/div, grey = 0400/div;
pg.beginDraw();
pg.noStroke();
while (i-- != 0) {
pg.fill(i*grey);
pg.rect(map(i, div, 0, width, 0), 0, wdiv, height);
}
pg.endDraw();
return pg.get();
}
@keren_m, as I've tipped you already, you should start by looking at eraseCanvas() 1st. And try to adapt it to your need.
For example, eraseCanvas() uses the current mouse coordinates to determine the point of origin.
I believe you would want the point of origin to be the center of the PImage instead, right?
Another issue is that eraseCanvas() expects that variables canvas & diam to pre-exist as global fields.
I think it'd be better to pass those as parameters instead.
The name eraseCanvas() isn't appropriate for what you intend to do now.
Change it to something like PImage cropImageCircle(PImage img, int diam).
The premise of the original eraseCanvas() is to erase pixels within a radius.
But you gotta make it copy pixels to another clean 100% transparent PImage at the same coordinates instead.
@_vk tnx for your reply!!..but the new image is on the size of the circle or it's the size of the origin image?because i need it to b on the size of the circle...and there is away that i can also blur the pixels that are inside the circle without putting all black screen, just leave the image and bluring just the pixels that are inside the circle in a way that fits with the image,like photoshop? ;)
There is not a newimage really. You could do one though. What I've done, was to just display the masked image over the canvas. You still with a 200x249 rectangle, only that all, but the masked circle area, are transparent pixels… So the origin to the image still being the top left corner of the original image. You can use image call instead of background, blur it, and overlay the unblurred one… Or the opposite. You might need another PGraphics maybe.
I think you may dig into those links, there are issues and also another way, which I'm not familiar with, of doing this. With PShape and texture() i think. I think those are faster. There are examples of that among those posts.
Little l8 for the party now... Anyways, just finished adapting eraseCanvas() into cropImageCircle()! #:-S
And as a bonus, there's a built-in trim feature too! The output PImage's dimensions match the diameter parameter! \m/
/**
* Crop Round Image (v1.0)
* by GoToLoop (2014/Jun)
*
* forum.processing.org/two/discussion/5618/crop-image
*/
static final String URL = "https://" + "upload.wikimedia.org/";
static final String FOLDER = "wikipedia/en/c/ca/";
static final String FILE = "Luigi_vacuum", EXT = ".jpg";
static final int DIAM = 0400, MARGIN = 050;
PImage rectImg, roundImg;
void setup() {
size(800, 600, JAVA2D);
noLoop();
smooth(4);
imageMode(CORNER);
//rectImg = loadImage(FILE + EXT);
rectImg = loadImage(URL + FOLDER + FILE + EXT);
roundImg = cropImageCircle(rectImg, DIAM);
println("Original Image Dimensions: "
+ rectImg.width + ", " + rectImg.height);
println("Rounded Image Dimensions: "
+ roundImg.width + ", " + roundImg.height);
}
void draw() {
background(0100);
set(MARGIN, height-rectImg.height >> 1, rectImg);
image(roundImg, width-roundImg.width-MARGIN, height-roundImg.height >> 1);
}
PImage cropImageCircle(final PImage inputImg, int diam) {
final int rad = (diam = abs(diam)) >> 1, radSq = rad*rad;
final color[] p = inputImg.pixels;
final int w = inputImg.width, h = inputImg.height;
final int cx = w>>1, cy = h>>1;
final PImage outputImg = createImage(diam, diam, ARGB);
final color[] q = outputImg.pixels;
final int minX = max(cx - rad, 0);
final int maxX = min(cx + rad, w);
final int minY = max(cy - rad, 0);
final int maxY = min(cy + rad, h);
for (int y = minY; y != maxY;) {
final float cySq = sq(cy - y);
final int rw1 = w*y, rw2 = diam*(y++ - minY);
for (int x = minX; x != maxX; x++)
if (sq(cx - x) + cySq <= radSq) q[rw2 + x - minX] = p[rw1 + x];
}
outputImg.updatePixels();
return outputImg;
}
Variables cx & cy represent the center of the cropped circle, its point of origin.
Rather than insert mouseX & mouseY back as @Chrisir said and how it was in the original eraseCanvas(),
let's make it more flexible and declare cx & cy as the method's parameters:
PImage cropImageCircle(final PImage inputImg, final int cx, final int cy, int diam) {
And pass mouseX & mouseY as the arguments for cx & cy: *-:)
Answers
Perhaps the example in the thread below can give ya some ideas on how to do it: *-:)
http://forum.processing.org/two/discussion/598/mousewheel-syntax-question-solved
Then that's not cropping, that's masking. There are lot of topics on mask() and friends.
[EDIT] For the record, it was indeed cropping, because the wanted result must have exactly the size of the circle (masking makes the pixels outside the masked area transparent, it doesn't remove them). I misunderstood the question.
@GoToLoop Thanks for you reply :)...but i dont understatnd how i can do the same thing with a image and copy what is inside the circle.
@PhiLho tnx!but were i can find it? u can please put a link? :)
Just createImage(), then copy every pixel from the original PImage which is within the radius area!
Take a look at eraseCanvas() function there. And adapt it to copy the selected pixels within radius!
@GoToLoop thanks!! i try to do it but i ran into some problems.i try to do it but i have a bug:"syntax error maybe missing a semicolon", i dont undrstand why?... i try to do 2 things :
1.when i'm clicking with the left mouse i need to copy the pixels that are inside the circle to a new image and draw it to the (0,0) pixels.
2.when i'm clicking with the left mouse i need to blur the pixels that are inside the circle.
i'll really appreciate your help!! i dont know how to resolve it..
this your example code that i try to use with some change of my:
@keren_m, as I've tipped you already, you should start by looking at eraseCanvas() 1st. And try to adapt it to your need.
For example, eraseCanvas() uses the current mouse coordinates to determine the point of origin.
I believe you would want the point of origin to be the center of the PImage instead, right?
Another issue is that eraseCanvas() expects that variables canvas & diam to pre-exist as global fields.
I think it'd be better to pass those as parameters instead.
The name eraseCanvas() isn't appropriate for what you intend to do now.
Change it to something like
PImage cropImageCircle(PImage img, int diam)
.The premise of the original eraseCanvas() is to erase pixels within a radius.
But you gotta make it copy pixels to another clean 100% transparent PImage at the same coordinates instead.
PhiLo means:
mask() site:processing.org
http://bit.ly/1mt8CHB
or
mask() site:forum.processing.org
http://bit.ly/1kPJkrs
@GoToLoop i try do do this but it's not working. i can't figure out why.u can please take a look? :)
@_vk tnx!but i don't understand how masking is helping me? :)
;)
@_vk tnx for your reply!!..but the new image is on the size of the circle or it's the size of the origin image?because i need it to b on the size of the circle...and there is away that i can also blur the pixels that are inside the circle without putting all black screen, just leave the image and bluring just the pixels that are inside the circle in a way that fits with the image,like photoshop? ;)
tnx! :)
There is not a new image really. You could do one though. What I've done, was to just display the masked image over the canvas. You still with a 200x249 rectangle, only that all, but the masked circle area, are transparent pixels… So the origin to the image still being the top left corner of the original image. You can use image call instead of background, blur it, and overlay the unblurred one… Or the opposite. You might need another PGraphics maybe.
I think you may dig into those links, there are issues and also another way, which I'm not familiar with, of doing this. With PShape and texture() i think. I think those are faster. There are examples of that among those posts.
Anyway here is the idea.
Little l8 for the party now... Anyways, just finished adapting eraseCanvas() into cropImageCircle()! #:-S
And as a bonus, there's a built-in trim feature too! The output PImage's dimensions match the diameter parameter! \m/
@_vk tnx!! i'll c what i can do with that.
@GoToLoop Amazing!tnx!!there is a chance to do it with mousex,mousey to be the center of the circle and not the center of the image? :)
line 43: insert mouseX and mouseY
Variables cx & cy represent the center of the cropped circle, its point of origin.
Rather than insert mouseX & mouseY back as @Chrisir said and how it was in the original eraseCanvas(),
let's make it more flexible and declare cx & cy as the method's parameters:
PImage cropImageCircle(final PImage inputImg, final int cx, final int cy, int diam) {
And pass mouseX & mouseY as the arguments for cx & cy: *-:)
roundImg = cropImageCircle(rectImg, mouseX, mouseY, DIAM);
Of course, comment out line #43 after that change:
//final int cx = w>>1, cy = h>>1;
. :-jP.S.: For mouseX & mouseY to work as cx & cy, the source inputImage gotta be displayed at (0, 0) coordinates I'm afraid! 8-|
yes, much better, thank you, gotoloop
;-)
i did it but it's not display the crop image.any idea?
where do you call cropImageCircle at all?
you need to call it....
probably in draw()
roundImg = cropImageCircle(rectImg, mouseX, mouseY, DIAM);
line 66:when i'm clicking i call it...
don't noLoop in 10 pls
also line 29 is not helpful
there is a small (rad) offset though to the right
Lo & behold the latest "Crop Round Image" (version 2.0): \m/
@Chrisir tnx 4 your helps :)
@GoToLoop really tnx it's was very helpful your code!!! =D>