Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Getting color values from image display  RSS feed

 
Jim Anderson
Greenhorn
Posts: 15
Eclipse IDE Java Notepad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm writing a computerized image sequentially. At each pass, I draw a colored-square plus lines extending from the top-to-bottom & left-to-right of the image. During each pass, I want to ensure that lines associated with the new square don't show up as passing through the old square(s). Sounds simple: if I write/draw lines piece-meal, I need only check that each new line segment doesn't pass through an existing square. If it does, I move on without drawing anything. I can write/draw new lines/points, but I don't know how to determine/read the color of existing points. I think java.awt.robot may help if I know the absolute coordinates of my (x.y) coordinates. Anyone have any thoughts? Thanks.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim Anderson wrote:At each pass, I draw a colored-square plus lines extending from the top-to-bottom & left-to-right of the image.

So am I right in thinking that every square will have up to eight lines coming from it - a bit like the centre square of a tic-tac-toe board - that extend to the edges of your "screen"?

During each pass, I want to ensure that lines associated with the new square don't show up as passing through the old square(s). Sounds simple: if I write/draw lines piece-meal, I need only check that each new line segment doesn't pass through an existing square. If it does, I move on without drawing anything. I can write/draw new lines/points, but I don't know how to determine/read the color of existing points.

I'm not sure why colour comes into it. Surely, either you want to draw the line if there's no square in the way or or you don't?

Also: are you OK with painting over other lines?

Personally, I'd start out with a grid of booleans that says if the pixel is "already painted on" or not; but I'm quite sure there are better ways.

I'm going to move this to our Swing forum, as you'll probably get a better response from guys who specialize in that stuff.

Winston
 
Piet Souris
Rancher
Posts: 1980
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jim,

assuming you are using a BufferedImage, you can easily find out the colour of each individual pixel with this call:



where bufim is the BufferedImage in question, and x and y are the pixel coordinates. If needed, you can then
split the integer 'colour' into the components A, R, G and B.

See the API for BufferedImage:

http://docs.oracle.com/javase/7/docs/api/

Greetings,
Piet
 
Jim Anderson
Greenhorn
Posts: 15
Eclipse IDE Java Notepad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston & Piet: Thanks for your thoughts.

Piet: Unfortunately, I'm not using "Buffered Image". If I were, your solution is spot on. But I'm drawing images on the screen [e.g., using Graphics g followed by g.drawRect(xstart,ystart,deltax,deltay)]. Each pass creates a filled rectangle plus lines extending from the sides to the edge of the screen. I'm trying to generate images reminecent of the great artist Piet Mondrian -- one rectangle plus lines at each iteration.

It helps (me at least) to draw rectangles-plus-lines in sequential iterations. This way the current image tells me when to stop iterating.

Winston & Piet: What do you think of this idea? In addition to my screen-display (described above), I create a second scratch array [could be a BufferedImage, or a Boolean] to track previously filled & blank pixels. I interrogate the second array to decide whether or not to color the next pixel as I draw line segments [e.g., using g.drawRect((xpos+1),ypos,1,1)].

Admittedly, I'm a JAVA newbie. But I'm really surprised that there's no command similar to g.drawRect(x,y,deltax,deltay) that generates the color at position (x,y). Let's call it g.getColor(int x,int y).

Best...

Jim
 
Piet Souris
Rancher
Posts: 1980
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jim,

I understand. I'm afraid that what you want is impossible to do, the way that you do it now.
Therefore I'm going to suggest to you a slightly different approach. That will involve some
extra programming (albeit minor) and maybe some reading in the API's, but I think that
this new approach will offer you the best of both worlds.

First of all a digression: you write directly to a JPanel. Have you ever wondered how it is
possible that when you cover your window by some other window, and later when you uncover your window,
that your JPanel still shows up in full glory? Your paintComponent-routine is not doing that repainting!
Well, that is because Swing uses what is called 'double buffering'. If you write to a JPanel, then in the
background, Swing draws to a BufferedImage, and when your writing is finished, it copies that BI
to the screen. Unfortunately, as far a as I know, we cannot make use of that background BI.

What I suggest is: let's copy this process! Now, the emphasis on this site is very much aimed towards letting
people discover themselves what to do, as much as possible, and rightly so. So in the next, I'll try to
give as little code as possible, but that you can quickly apply it, and know where to look for additional
information.

Okay, here's what you can do.

First of all, in stead of drawing directly to your JPanel, we create a BufferedImage, and draw to this BI.
You can use the exact same drawing commands for this. Only, in stead of using the graphics environment
of the JPanel, we use the graphics environment of the BI.

By using this BI for drawing, you can inspect every pixel before drawing new pixels, in the way I wrote
earlier. You can also draw a single pixel by issuing

So that is the best of this world.

Now, the question is: now that I write to a BI, how can I get that on my screen? Well, for this to make
possible, we need to change the paintComponent method of the JPanel. The only thing needed in this method
is that it should draw the BI to the JPanel. That's all!

And then possibly the biggest reward of all: after your Mondriaan routine has finished (assuming it does!)
it takes you just one line of code to save your masterpiece to disc, so that you can show it around the world.

Now, to save you the trouble of finding out all that you need to know, I'll give some details.

First: create two additional members for your class (whether these are static members or instance members,
depend on how you exactly programmed your class).

These two members are:



Now, suppose your JPanel measures WIDTH x HEIGHT pixels, so we create the BI:



and then, we create the graphics environment for this BI:



Now, in your create_Mondriaan painting routine, in stead of using your current graphics environment,
you use g2d_Mondriaan. Of course, here's the place to check the individual pixels before
adding your new rectangles.

Next, the question is: how are we to see the progress being made?

Well, the easiest thing would be: after you have generated one or more rectangles รก la
Mondriaan, you just call JPanel.repaint().
As said, for this to work, your JPanels paintComponent must be something as follows:


And, finally, when your new creation is finished and looks enough like a genuine Mondriaan,
then you can save your millions worth creation with the command:



Read the API's for more information.

Promise us to show us some of your new Mondriaan World Beaters?

Greetings,
Piet

PS: first, with this approach you don't need this boolean rectangle anymore.

Secondly: a couple of weeks ago I was watching television, and there was
an interview with two men and a woman. They were finalists in a competiton
that was about: create a program that creates Mondriaan paintings. A jury
was to decide which program would do best. All three explained a little
what algorithms they were using, and what, in their opinion, characterized
Mondriaan. Well, I was watching mouth-open, I couldn't imagine it to be
possible to do things like that. Now, are you maybe one of those finalists?

;)
 
Jim Anderson
Greenhorn
Posts: 15
Eclipse IDE Java Notepad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet: Thanks for ALL your comments. I'll incorporate them & keep you posted.

A few thoughts on Mondriaan art (unrelated to JAVA):

First, I hope I can find the TV program you mentioned. I have a personal "specification list" for what constitutes Mondriaan-type art. It would be great to see lists generated by others.
Second, I'm not aiming at "Great Art": Rather, I want to create a "Massively Open On-Line Course" (MOOC) on "Generative Art" = abstract art generated by computers. My intended audience is people like myself, who attend Adult Ed classes [This avoids the thorny issue of university course credit]. There's a lot of Gen Art on the web, but I've found nothing that addresses "relative aesthetics" = what makes 1 image better/worse than a second image. Most people -- including art critics -- believe this is impossible: likes & dislikes are far too personal. Perhaps so, but I'll bet that broad guidelines can be established. Since Mondriaan-type art is fairly easy to generate, it makes a good starting point. My first test: given a "true & a "bogus" Mondriaan, a viewer correctly identify the "true Mondriaan"?

Best...

Jim
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!