9
$\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$
    – rm -rf
    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$
    – Mr.Wizard
    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$
    – Mr.Wizard
    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$
    – Chirese
    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$
    – Chirese
    Apr 3, 2012 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.