10
$\begingroup$

I need to figure out a way to find out the RGB color value at a certain coordinate in a Graphics object. The Graphics object I am dealing with is continually Dynamically updated, so it is made of moving objects. How can I find the color at a certain point in this moving graphics object.

There is a function, for Image type, called ImageValue which will give color at the given point, but then I have to somehow convert the Graphics to a Image each time I want to check the color at a point, since the Graphics is changing. I have the following code to do that, but it takes much too long to do so, and causes a visible pause. I replace the Dynamic type of the Graphics with Image.

image = screen /. Dynamic -> Image 

The above calculation takes too long, when I checked the timing of it.

What I am asking for is a faster, easier way to make a Dynamic Graphic an Image so I can take color like that, or a way to take color at a certain point in Graphics.

Please help, A frustrated student.

Code except:

screen = Dynamic[Show[{backdrop, carsList}]; image = screen /. Dynamic -> Image; points = ImageValue[image, {newX, newY}]; For[i = 1, i < Length[points], i++, If[points[[i]] == {0, 0, 2/3} || points[[i]] == {1, 0, 0}, valid = False; Break[]; ]; ]; 

points would usually hold more color data for points, I shortened code.

$\endgroup$
4
  • $\begingroup$ See this question and its answers. Is that what you're looking for? $\endgroup$ Commented Apr 1, 2012 at 4:19
  • 1
    $\begingroup$ Please consider including (a stripped down version of) your code in your question, so that those wishing to help do not have to recreated your project from scratch and a lot of guesswork. $\endgroup$ Commented Apr 1, 2012 at 4:19
  • $\begingroup$ @R.M I presume he wants to go the other way: a simple "eyedropper" tool (Photoshop terminology). $\endgroup$ Commented Apr 1, 2012 at 4:21
  • $\begingroup$ I edited to include code. It is a simplified version of what I have, with a lot of extra variables removed,etc. $\endgroup$ Commented Apr 1, 2012 at 5:29

1 Answer 1

5
$\begingroup$

This method uses Intersection to test the colours, which should be faster than looping through the list of sample points.

I.e. with sample image, a:

a = Graphics[{Yellow, Rectangle[{0, 0}, {300, 185}], Inset[Graphics[{Blue, Rectangle[{0, 0}, {20, 10}]}], {100, 140}, {0, 0}, {20, 10}]}, PlotRange -> {{0, 300}, {0, 185}}, ImageSize -> 300]; samplepoints = {{101, 141}, {117, 141}, {117, 148}}; testcolours = {{255, 255, 0}, {255, 255, 255}, {0, 0, 0}}; b = Rasterize[a]; pointcolors = Part[b, 1, 1, #2, #1] & @@@ samplepoints; valid = Intersection[testcolours, pointcolors] == {} 

True

The test does not find yellow, white or black at coordinates (101, 141), (117, 141) or (117, 148) and so sets valid True.

Note

I opted not to use ImageValue as I found its results unpredictable, e.g.

newsamplepoints = {{1, 1}, {101, 141}, {117, 141}, {117, 148}, {300, 185}}; b = Rasterize[a]; pointcolors = Part[b, 1, 1, #2, #1] & @@@ newsamplepoints; Graphics[{RGBColor @@ #, Disk[]}, ImageSize -> 20] & /@ pointcolors 

enter image description here

pointcolors = ImageValue[a, newsamplepoints]; Graphics[{RGBColor @@ #, Disk[]}, ImageSize -> 20] & /@ pointcolors 

enter image description here

There are only colours yellow and blue in the sample graphic.

The rasterizing method does seem to be a little slower though. You could use either.

moresamplepoints = Transpose[RandomInteger[{1, #}, 10000] & /@ {300, 185}]; Timing[(b = Rasterize[a]; pointcolors = Part[b, 1, 1, #2, #1] & @@@ moresamplepoints;)] 

{0.078, Null}

Timing[pointcolors = ImageValue[a, moresamplepoints];] 

{0.031, Null}

$\endgroup$
1
  • $\begingroup$ Excellent, Thank you! $\endgroup$ Commented Apr 3, 2012 at 18:43

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.