We are about to switch to a new forum software. Until then we have removed the registration on this forum.
What I'm trying to do: create a bunch of ellipses (in a grid) that each have one of an array of colors and that each mask one or more rectangles that also have a variable color from the same array. I've succeeded at (1) creating a masked shape, (2) duplicating it in a grid, and (3) creating an array of colors. Right now I'm trying to get that array to affect the colors but I'm failing. What am I doing wrong? I'm getting an error "expecting EOF, found 'colorset'." Pretty sure I have my file set up incorrectly. Any tips?
/**
* Draw rectangles inside of circles
* 2017-08-22
**/
PGraphics sourceImage;
PGraphics maskImage;
int colorset;
color [] colorsetarray = {
color(#3AC459),
color(#3D8CFF),
color(#8CD6ED),
color(#F7CC68),
color(#F77068),
color(#576984),
color(#7A9BB0),
color(#D8E8ED),
color(#EAF4F7) };
colorset = colorsetarray[(int)random(0, 8)];
void setup() {
size(800, 800); //size of canvas
noLoop();
smooth();
}
void draw() {
for (int y = 20; y < height-8; y += 120) {
for (int x = 20; x < width-80; x += 120) {
// create source
sourceImage = createGraphics(100, 100); //size of drawing
sourceImage.beginDraw();
sourceImage.background(colorsetarray[(int)random(colorsetarray.length)]); //color the background
sourceImage.fill(colorsetarray[(int)random(colorsetarray.length)]); //color the rectangle
sourceImage.translate(width/2, height/2);
sourceImage.rotate(radians(45));
sourceImage.noStroke(); //take the stroke off of the rectangle
sourceImage.rect(-600, -200, 80, 500); //locate the rectangle and draw it
sourceImage.endDraw();
// create mask
maskImage = createGraphics(100, 100); //size of mask
maskImage.beginDraw();
maskImage.ellipse(50, 50, 100, 100);
maskImage.endDraw();
// apply mask
sourceImage.mask(maskImage);
// show masked source
image(sourceImage, x, y); //move the chip here
}
}
}
Answers
@Petros -- to start, this line is not a declaration:
...so it can't go in the header. It has to appear in a function -- specifically, put it in setup().
If you really wanted to, you could combine it with its declaration and put it in the header AFTER the field that it references:
...but don't. setup() is better.
Thanks Jeremy. That fixed the problem of the sketch running (working now, yay!), but my spheres are all coming out black. Do you see what am I doing wrong?
Errors with relative motion. You need to review
For example this:
You are in a 100x100 image, and you just moved to 400x400, using variables based on the width of your sketch. So you are way off the screen. Everything you draw will be off the screen.
This looks wrong. What, specifically, are you trying to do? Better to anchor your rect at 0,0,x,y and use translate to place your drawing origin.
Color: try...
...does that work? If it does, now you can work out the placement. Once you've worked out the placement, then you can fix your color code. One thing at a time.
Are you initializing colorsetarray correctly? In setup, try:
Does it contain a set of different values? If not you should use a different method for setting up your array -- try checking the color reference page:
YEEESSSSS! It's working! Thank you so much for the help!
@Petros -- congratulations -- and it looks beautiful.
Thanks! It's getting there. Not sure if I should start a new thread or not, but I have another question. I'm now trying to save a few things from the sketch: (1) the entire image with all the circles, and (2) each individual circle shape. I added a save() at the end which works, but my saveFrame() in the for loop, it's doing what I would expect (saving as the sketch renders), but not what I want (saving each circular shape element). Any suggestions about how I would get to a place where for each time I run the sketch each individual shape is exported to a uniquely named .png? Maybe I should add another for loop and put the save in there? LMK if I should post a new question.
Example of output:
My code: /** * Draw rectangles inside of circles * 2017-08-22 **/ PGraphics sourceImage; PGraphics maskImage;
Good idea keeping it all in one thread -- much easier to understand the context and give feedback.
After you run sourceImage.mask(maskImage), you have a separate completed image object named sourceImage in memory. Now you can save that object, rather than the whole screen, with sourceImage.save()
Cool. That's saving the last circle each time I run it, but not all the circles. I've read a few threads but can't figure out how to increment the filename. Any suggestions? The other thing that I'm struggling with is centering the rectangle inside the circle. I read the canvas/grid article you mentioned (in another thread?) several times, and I've cleaned up my code some since then, but still can't figure out how to center the rectangle.
Okay, think I figured the part about centering the rectangle. Still don't know about saving out each one:
The ###### in the filename gets replaced with the frame number. But this is the same for all values of your for loop as they are all drawn in the same frame. So each is overridden by the next meaning you only see the last.
Add X and y to the filename to save all of them.
And look at Java's simpleDateFormat...
Thanks @koogs. Is simpleDateFormat included in processing already or do I have to add a library? I found this and this but my code isn't working for it. I put this in the setup section
But the console (right term?) says "The function "SimpleDateFormat(String) does not exist". I'm probably doing something obviously wrong. Any pointers on how to do this right? I've read this and this.
Definitely get your point about the saveFrame() and #####; that was kind of a shot in the dark. When you say "Add X and y to the filename to save all of them" I'm not sure what you mean. Can you elaborate for me?
https://Forum.Processing.org/two/discussion/20006/is-there-a-way-to-access-a-fraction-of-a-second-of-the-system-clock-not-millis-related#Item_1
Yeah, sorry, you'll need to add an import.
The current problem is that your filenames aren't unique so it's overwriting files. By including the current X and y values in the filenames (or, maybe, some new index value that increments per item) then they will be unique and won't overwrite.
Yes! I'm so psyched. I added this to my code and it's now saving out the circles individually.
before Setup:
int file_number=0;
and then in my two for loops I added:
I'm also really psyched that they're exporting with transparency. Thank you guys so much for your help! Now to try and get a handle on the date format stuff...(apologize for bad code formatting above; I can't figure out how to fix it.)
Congratulations!
Note that the code will produce many images during the same second -- hence same file name, hence overwriting. That's why you also need x y or something unique as @koogs points out.
P.S. your code isn't formatting in the post above because it needs a blank line above and below.
Cool. Fixed my formatting. I've got an incrementing number to keep the files unique (I think?). Now I'm having trouble incorporating, @GoToLoop, your suggestion. The code looks really simple, but I can't get it to work. I added this to my setup:
And then have this for my save in the for loop:
But I'm getting the error "String literal is not properly closed by a double quote." Why should
file_number
not need a double quote butformatted_date
does? Or, any suggestions on how to properly put the formatted date into the filename? I'm really thankful for all the help you folks have provided!Thanks @GoToLoop; definitely helpful. Except I can't figure out how to change the path where this image would be saved to. If I wanted to put the files on my (mac) desktop, how would I do it? I'm trying to figure out how to learn from the code you posted and I want to get this to put the files in a folder I control.
IMO, best place to place program's files is inside the very same folder the program is. $-)
However, if you wanna pick another folder for them, you've gotta specify its full path as you had already done in your own latest version, rather than using dataPath() like I did in mine. :>
Another (somewhat unrelated) question: Does anyone know what I could do to avoid some of the fuzz around the edge of my circles? I'd love them to be crisp. It seems to happen whether or not I have smooth(); in the setup section or not. Here's what I mean:
I also have it set to noLoop();
For default JAVA2D renderer, AFAIK, best sampling level is 3:
smooth(3);
^#(^https://Processing.org/reference/smooth_.html
Perhaps you may try out noSmooth() instead? :-??
https://Processing.org/reference/noSmooth_.html
Hmm, noSmooth definitely isn't it; that gives me no anti-aliasing. Tried smooth(2), smooth(3), and smooth(8), but didn't see the fuzz go away.
Try out other renderers like FX2D, P2D & P3D.
P2D & P3D can use higher sampling levels such as 8. Maybe even more. $-)
Dunno yet FX2D's max level sampling though. 8-|
Isn't the fuzz just the anti aliasing?
Maybe the problem is that it's doing the anti-aliasing using a background colour different to the colour is ending up on and baking some of that colour into the dot image. Ie a light dot on a dark background will have a fringe of dark pixels. Copy the dot to a light background and the fringe will be more visible. I haven't run the code though so that just a guess.
I'd be tempted to use vector graphics, export to PDF or svg. But if a rewrite though.
This btw is bad
Because : isn't valid character in Windows filenames. But I guess you've fixed that.
Also, why are you creating the mask image every single time when it doesn't ever change. Make it a global variable, create it in setup.
Thanks for those points! I haven't got the simplified dating working yet, so hopefully I'll fix the : if and when I get that working in a more streamlined way. But I'll look into the other renderers and that's a good point about the mask.
The fuzz is heavier on the top left (where it seems egregious) than it is on the bottom right (where it seems normal).
Hmm, that might be it -- you could try using background(255) / background(128) / background(0) in PGraphics during the mask process to see if it helps.
I've stalled a bit on this. Fixed the part about creating the mask over and over, fixed the :'s in the date format (which I still haven't successfully used), and tried a few of the different rendering things, and tried the background color idea (didn't seem to cut down the fuzz).
I'll probably come back to that stuff to make the code cleaner and more manageable, but for the meantime I'm really curious how I can vary the number of rectangles that are drawn within the circle. Right now I have two for loops to make the grid; I think I want to make a for loop that will draw more rectangles inside each circle. I've been thinking about it for a few days but I can't figure out how to approach it. I know I need to create a variable that varies the number of rectangles that get drawn, and I suppose that variable needs to be defined within the for loop, but how do I make it work? How can I tell it to draw between 2 and 10 rectangles inside each circle, each of which rectangle has a different x and y position and size that I can tweak? Any advice in that direction would be sweet. Here's what I have now in that section:
@Koogs, the anti-aliasing is really bugging me and I can't fix it. Is there a simple way to change my program from creating .pngs to creating and saving vector .svgs or .pdfs? You said it would require a rewrite. Any tips on how I would go about that?
Too late to look into that today. Maybe tomorrow.
The anti-aliasing, if that's what it is, looks asymmetric, which is odd.
That's a for loop.
Those are already the arguments to the rect() function.
You can randomize the arguments, or make them a sequence based on i, or draw them from a list like an array, etc.
You can also make that its own function --
drawRect();
Thanks for that Jeremy. I'm trying out your suggestion which mostly makes sense to me, but, don't laugh, I can't get the rectangles to stop drawing after they've reached the random number between 2 and 10. Do I need to add a count or something to check if i has reached that variable number between 2 and 10? Here's the full test sketch I'm working on...
re the masking...
add
maskImage.save("mask.png")
and examine that...WOW. @koogs, what a find! The mask was getting drawn with a stroke which was causing the fuzz. Here's the mask before I put a noStroke() on it:
And once I fixed that the fuzz went away. Woohoo!
I also did a bunch of code refactoring (thanks @jeremydouglass for the hints, and Daniel Shiffman on YouTube) which enabled me to work in the additional for loop. I'm pretty psyched about these results.
Now maybe I'll have time to figure out the simpler date formats. Thank you guys for your insights!
Can you paste the two lines where you save items?
Sure thing. Here's one (note I changed my createGraphics variable names, e.g. "maskedContent")
And the other