views:

31

answers:

2

I have, as an example, the following two images:

http://img571.imageshack.us/i/spain.jpg/
http://img97.imageshack.us/i/spainoverlay.png/

I want to load the second and detect the transparent areas for use as selections to which I can apply some processing, but I don't have the first clue how to start. I'm familiar with loading images and drawing shapes and text on them, but that's about it.

How do I go about doing some kind of "magic wand" detection on the transparent areas to obtain some array of points or other definition of the area for manipulation?

Edit: In the second image, the white areas are actually the transparent areas. They show up white thanks to imageshack's background color.

A: 

You can get check whether a pixel is transparent by checking its alpha value (0 is fully transparent, 255 is fully opaque) with Bitmap.GetPixel(), if Bitmap objects are what you're using to load images into.

If you just need to do something with each transparent pixel, I guess there's no need to create a selection in a separate object. Just iterate through the pixels, if one is transparent do what you have to do.

If you do need to create a selection, then you can use a separate 1 bit-per-pixel bitmap of the same size as your original image. White represents the selected area, black not selected (or opposite, your choice).

See: http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx

Mau
+1  A: 

This would seem like a simple problem of only displaying the full map image, and mapping the cursor coordinate when moved over that image to the corresponding coordinate of the mask image. You could do two things here. Keep the mask image black and white, and have a map of each area associated to something that defines what you want to do when that area is hovered. Or, change your mask to a multi-colored image, and simply map each color code to something that defines what you want to do when that area is hovered. I personally would choose the latter, as it is a lot simpler, and you would have approximately 16 million possible zones that could be used (given 24 bit colors).

Given a simple mapping type:

class ZoneMap
{
    public Color MappedColor { get; set; }
    public Action OnHover { get; set; }
}

You could look up the mapped zone by translating the mouse coordinates of the source image to the corresponding coordinates of the multi-color zone map image, look up the ZoneMap entry by color, and invoke its OnHover action:

var spainZones = new ZoneMap[]
{
    new ZoneMap { MappedColor = Color.Red, OnHover = new Action(RedHandler) },
    new ZoneMap { MappedColor = Color.Blue, OnHover = new Action(BlueHandler) }
}

var color = getZoneColor(Mouse.X, Mouse.Y); // translate source mouse coords to colored zone map coords and get color
var zone = spainZones.FirstOrDefault(zm => zm.MappedColor == color);

zone.OnHover();

I know this is very rough. If I had more information about what you want to do on hover of a particular zone, I might be able to provide more.

jrista
This is close to what I want, I think. The basic idea is to process the individual areas distinctly (think puzzle pieces). The end result is something like the way warfish.net does with their game maps. I want to present the user with the original image, detect a click, and do something with all adjacent pixels of the same color (fill the area with a color, for example)
Chris
Using adjacent pixels of the same color according the overlay, I mean. The original source image is for presentation purposes only - the intent is for the overlay to define the actionable areas of the image.
Chris
@Chris: Right, only the original source image would be displayed. However, so long as your source image and the zone map image are the same size, you can easily map mouse coordinates when hovered over the source image to the zone map image. Once you have the color of the zone, looking up the correct ZoneMap entry by color, and invoking its OnHover action, would be rather trivial.
jrista
Ok, I get what you're saying, but let's say I wanted to take the area mapped to a specific color and do, say, a gaussian blur on it. I'm not worried about the algorithm for the manipulation at this point, but how would I go about manipulating the entire mapped zone as a whole, rather than pixel by pixel color checking?
Chris
There are probably a variety of approaches. Since the OnHover action of each zone is unique, you could pretty much do anything you want. If you wish to blur the area of the zone hovered, you could load up another image that masks out just the zone you wish to blur, then apply a blurring algorithm. Space is cheap these days, so I wouldn't worry so much about using a single mask image for all of the things you wish to do. Solve each problem individually. A colored mask solves the hit-test problem. A unique grayscale mask can solve the blurring problem, etc.
jrista