Jump to content


Photo

Identify colored areas


  • Please log in to reply
9 replies to this topic

#1 tomasart

tomasart

    GMC Member

  • GMC Member
  • 201 posts

Posted 24 July 2012 - 09:21 PM

I have an picture with several pink squares. Is there a way to indentify where the pink scares are???

Any help or idea will be very apreciated.
  • 0

#2 Lighteningmoon

Lighteningmoon

    GMC Member

  • GMC Member
  • 81 posts
  • Version:GM7

Posted 24 July 2012 - 10:28 PM

are the pink squares in one sprite or are they all different objects?
  • 0

#3 TheMagician

TheMagician

    GMC Member

  • GMC Member
  • 235 posts

Posted 24 July 2012 - 10:34 PM

You can create a surface from your picture and use
surface_getpixel(id,x,y)
It returns the color of the pixel at position x,y.

However, this is a very slow function so you definitely shouldn't use it in the step event.
  • 0

#4 tomasart

tomasart

    GMC Member

  • GMC Member
  • 201 posts

Posted 25 July 2012 - 12:24 AM

You can create a surface from your picture and use

surface_getpixel(id,x,y)
It returns the color of the pixel at position x,y.

However, this is a very slow function so you definitely shouldn't use it in the step event.


can you give me an example please? thanks very much
  • 0

#5 dannyjenn

dannyjenn

    GMC Member

  • GMC Member
  • 2235 posts
  • Version:Mac

Posted 25 July 2012 - 12:44 AM

Example:
// sprite0 is whatever sprite you want to find the pink pixels on
// xx is the x location of the sprite's top-left corner
// yy is the y location of the sprite's top-left corner
array[0,0] = noone;
array[0,1] = noone;
index = 0;
pink = make_color_rgb(255,200,200); // or whatever colour you want to find
for(a=0;a<=sprite_get_width(sprite0);a+=1){
    for(b=0;b<=sprite_get_height(sprite0);b+=1){
        if(draw_getpixel(a+xx,b+yy)==pink){
            array[index,0] = a;
            array[index,1] = b;
            index += 1;
        }
    }
}
It will make an array called array, and in array[0,0] will be the x location of the first pink pixel found, array[0,1] will be the y location (relative to the sprite's top-left corner) of that pink pixel, array[1,0] will be the x location of the second pink pixel found, array[1,1] will be its y location, and so on. And index will be the size of the array... if index is 0 that means that the sprite contained no pink pixels.

This most likely will not work... draw_get_pixel is very slow. Even if it is being used in an event that only executes once, just having it in such a loop will probably freeze the game for brief moment. But it's worth a try.

Also, that will return individual pixels. Not sure if that's what you meant by "squares".

Edited by dannyjenn, 25 July 2012 - 12:45 AM.

  • 0

#6 tomasart

tomasart

    GMC Member

  • GMC Member
  • 201 posts

Posted 25 July 2012 - 08:44 AM

Example:

// sprite0 is whatever sprite you want to find the pink pixels on
// xx is the x location of the sprite's top-left corner
// yy is the y location of the sprite's top-left corner
array[0,0] = noone;
array[0,1] = noone;
index = 0;
pink = make_color_rgb(255,200,200); // or whatever colour you want to find
for(a=0;a<=sprite_get_width(sprite0);a+=1){
    for(b=0;b<=sprite_get_height(sprite0);b+=1){
        if(draw_getpixel(a+xx,b+yy)==pink){
            array[index,0] = a;
            array[index,1] = b;
            index += 1;
        }
    }
}
It will make an array called array, and in array[0,0] will be the x location of the first pink pixel found, array[0,1] will be the y location (relative to the sprite's top-left corner) of that pink pixel, array[1,0] will be the x location of the second pink pixel found, array[1,1] will be its y location, and so on. And index will be the size of the array... if index is 0 that means that the sprite contained no pink pixels.

This most likely will not work... draw_get_pixel is very slow. Even if it is being used in an event that only executes once, just having it in such a loop will probably freeze the game for brief moment. But it's worth a try.

Also, that will return individual pixels. Not sure if that's what you meant by "squares".


I dont need it in the step event. I only need one time know where my scares are. My scares are 50x50 pixel each. Your example will fill the array with each pixel??? That means each scare have an array of 50 ?
  • 0

#7 tomasart

tomasart

    GMC Member

  • GMC Member
  • 201 posts

Posted 25 July 2012 - 12:52 PM

ok, i will try to make my problem more graphical:

This is the image i have.

Posted Image

Is only one objet. And i want to identify the positions of the PINK scares. I know it's dificult, but as i say any hel will be apreciated.
  • 0

#8 @Alex@

@Alex@

    Retired GMC Reviewer

  • Reviewer
  • 3145 posts
  • Version:Unknown

Posted 25 July 2012 - 01:20 PM

Before I try and help I have to ask what's with using scares instead of squares most of the time, you've used it correctly some of the time but not others. Well not strictly speaking correctly judging from your image they have rectangles but that's a minor point at best. <br><br>We can grab the pixels one by one and feed the pink ones into a ds_grid which we can then use for checking later. This is just off the top of my head so probably doesn't work and needs some tweaking but this would be the general idea.<br><br>
<br>

<br>

//Set Up Variables<br>

var W , H , Colour , Grid ;<br>

W = room_width ;<br>

H = room_height ;<br>

Colour = 0 ;<br>

ColourToCheckFor = c_red ;<br>

Grid = ds_grid_create(W,H) ;<br>

<br>

<br>

//Save the sprite to a surface<br>

var Surf ;<br>

Surf = surface_create(W,H) ;<br>

surface_set_target(Surf) ;<br>

draw_sprite(sprite0,0,0,0) ;<br>

<br>

<br>

<br>

//Loop Through the Surface Pixel by pixel<br>

<br>

for(a=0;a&lt;=room_width;a+=1)<br>

&nbsp;&nbsp;&nbsp; {<br>

&nbsp;&nbsp;&nbsp; window_set_caption("Row : " + string(a)) <br>

&nbsp;&nbsp;&nbsp; for(b=0;b&lt;=room_height;b+=1)<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Grab the Colour of the Pixel<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Colour = draw_getpixel(a,b) ;<br>

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(Colour == ColourToCheckFor)<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ds_grid_set(Grid,a,b,1) ;<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>

&nbsp;&nbsp;&nbsp; }<br>

<br>

return Grid ;<br>

<br><br>Edit : <br>You should free the surface before returning anything or you'll get a memory leak. You should look into snapping the rectangles to a grid if possible so you can skip some pixels and save some time , a 300 * 300 room should take about 10-15 seconds using this script which I wouldn't class as acceptable unless you really need to. If they aren't created dynamically I'd look into declaring them manually (or creating a seperate program to output a grid or array of it's positions from dragging a box over it the pink areas).<br>

Edited by @Alex@, 25 July 2012 - 02:13 PM.

  • 0

#9 dannyjenn

dannyjenn

    GMC Member

  • GMC Member
  • 2235 posts
  • Version:Mac

Posted 25 July 2012 - 01:44 PM

I'm not exactly sure what you want because you say they're 50*50 pixels but your picture they're much larger than that and not even squares.

Anyway, I've modified my code... this will get you the upper-left corner of every pink rectangle
// sprite0 is whatever sprite you want to find the pink pixels on
// xx is the x location of the sprite's top-left corner
// yy is the y location of the sprite's top-left corner
array[0,0] = noone;
array[0,1] = noone;
index = 0;
pink = make_color_rgb(255,200,200); // or whatever colour you want to find
for(a=0;a<=sprite_get_width(sprite0);a+=1){
    for(b=0;b<=sprite_get_height(sprite0);b+=1){
        if(draw_getpixel(a+xx,b+yy)==pink){
            if((draw_getpixel(a+xx-1,b+yy)!=pink) &&
               (draw_getpixel(a+xx,b+yy-1)!=pink)){
                array[index,0] = a;
                array[index,1] = b;
                index += 1;
            }
        }
    }
}
Keep in mind, that's just as slow as the above code (actually, it's slower), but it will only get you the x and y of each rectangle (so in the end, only array[0,0], array[0,1], array[1,0], array[1,1], array[2,0], and array[2,1] will be filled since there are 3 rectanges). It will not work if you have overlapping rectangles, but it would work for your example.

Also, you can speed the code up quite a bit if the rectangles were snapped to a grid. Doesn't seem to be the case for your example, but if they were snapped to say, a 16*16 grid, you'd increase a and b by 16 rather than 1 and the loop would complete 256 times as fast.

Edited by dannyjenn, 25 July 2012 - 01:51 PM.

  • 0

#10 tomasart

tomasart

    GMC Member

  • GMC Member
  • 201 posts

Posted 25 July 2012 - 02:01 PM

I'm not exactly sure what you want because you say they're 50*50 pixels but your picture they're much larger than that and not even squares.

Anyway, I've modified my code... this will get you the upper-left corner of every pink rectangle

// sprite0 is whatever sprite you want to find the pink pixels on
// xx is the x location of the sprite's top-left corner
// yy is the y location of the sprite's top-left corner
array[0,0] = noone;
array[0,1] = noone;
index = 0;
pink = make_color_rgb(255,200,200); // or whatever colour you want to find
for(a=0;a<=sprite_get_width(sprite0);a+=1){
    for(b=0;b<=sprite_get_height(sprite0);b+=1){
        if(draw_getpixel(a+xx,b+yy)==pink){
            if((draw_getpixel(a+xx-1,b+yy)!=pink) &&
               (draw_getpixel(a+xx,b+yy-1)!=pink)){
                array[index,0] = a;
                array[index,1] = b;
                index += 1;
            }
        }
    }
}
Keep in mind, that's just as slow as the above code (actually, it's slower), but it will only get you the x and y of each rectangle (so in the end, only array[0,0], array[0,1], array[1,0], array[1,1], array[2,0], and array[2,1] will be filled since there are 3 rectanges). It will not work if you have overlapping rectangles, but it would work for your example.

Also, you can speed the code up quite a bit if the rectangles were snapped to a grid. Doesn't seem to be the case for your example, but if they were snapped to say, a 16*16 grid, you'd increase a and b by 16 rather than 1 and the loop would complete 256 times as fast.


Hoho, thanks a lot for your code. I'is exactly what i need. Thanks @Alex@ too for your time and help.

And sorry for my bad English.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users