How could I reduce the complexity of an image map? - html

I'm using KImageMapEditor on Linux (Ubuntu) to create an image map. The shapes in the image are a little complex so I'm using the freehand tool to draw them. However, this is really the same as the polygon tool so the shapes have ended up with a lot of points, which has made the HTML pretty huge.
Does anyone know of a way to reduce the complexity of the shapes, like "smoothing out" the lines?
I should also mention the reason I want the shapes to be fairly accurate is because I'm intending to do something like this, where each shape is highlighted on mouseover: http://davidlynch.org/js/maphilight/docs/demo_usa.html

Since users aren't going to click to the pixel, give them some leeway and create a "sloppy" map which roughly outlines each shape instead of clinging to the actual pixel outline.
This is in the same way as you don't expect a click on a link to fail just because you click on the background which shines through the text. You expect the bounding box of the text to act as the click-able area instead of the "black pixels".

Algorithm: Given three consecutive points, eliminate the middle point if the angle created is less than some tolerated error e.
Polygonal path simplification with angle constraint

Related

How can I overlay multiple PNGs and have each of them clickable in their visible area?

I need to set up a clickable image system for dynamically created content. The image consists of a background image, and several grey-scale mask images.
Background Image:
(source: goehler.dk)
Masks:
(source: goehler.dk)
,
(source: goehler.dk)
,
(source: goehler.dk)
,
(source: goehler.dk)
,
(source: goehler.dk)
Each area, defined by a mask, should be highlighted on mouse over, clickable on the image, and open a certain link.
How do I do this the smartest way? I need this to be responsive, and work with a couple of hundred masks.
I haven't tried anything yet, but I've done some research, which have resulted in two possible solutions:
A. Trace the masks, and create imagemap coordinates for each, which can be overlayed the original image. (seems difficult, especially with masks that have holes).
B. Layer all masks on top, and shuffle through them and search for white pixels. (seems processor intensive, shuffling though hundres of images).
I hope however, that there is a third, simpler, more optimized and more elegant solution?
Any advice?
I'd love to hear from anyone who have any experience with something similar.
You should try to precompute as much of this as possible, especially because it's probably not feasible to download hundreds of these mask images in the user's browser.
Your solution A seems like a good way to go, provided it's possible to compute coordinates from the pixel shapes.
Another idea could be combining the mask images in a single image by color-coding the mask shapes (filling each shape with a different color). Colors can be assigned randomly as long as they are used only once. Along with that, provide a simple lookup table for the color-to-shape mapping (e.g. #f00 => cube, #0f0 => donut, ...). Now, when the original image is clicked:
Find the pixel coordinate of the click
Lookup the color in the mask image at the same coordinate
Lookup the shape for the color in the lookup table
First of all, even with 100s of masks, this should not be slow, because the required algorithm has a complexity of O(n) and that is not slow.
The only bottleneck you will have is the pixel lookup, which is an expensive operation (unless you do certain modifications).
I would go with B.
Lets say your mouse coordinates are x:400, y:300, relative to your background image which has the dimensions 800x600.
You would iterate over all masks, and check:
mask.getPixel(400, 300) == white?
If so, use that mask, blend it over the original image with a specific alpha factor so the background get grayed out.
The bottleneck is: mask.getPixel()
You would have to do that n times if you have n masks and its the last one.
As I stated, its an expensive lookup; so can you optimise it?
Yes, cut out unnecessary look-ups by using: bounding boxes.
But to use bounding boxes, you must first create the bounding box data for each mask, which you could do once when you load (no problem).
The bounding box defines the upper left and bottom right corner that "bounds" the white area snugly. In other words, you must determine min and max X & Y coordinate where the pixel is white.
If the mouse coordinates are outside of this box, do not bother making a lookup, as it will certainly not be in the white area.
Edit: Since I was bored, I went ahead and implemented it...
Check it out.
//preProcessMasks() & trackMouse() is where everything happens
Gotto have the background image "img.jpg" and the masks "1.jpg" .. "5.jpg" in the same folder!
Works with firefox, chrome says "The canvas has been tainted by cross-origin data"... its a quick n dirty hack, do whatever you want with it, if its of any use to you!

After Effect Bezier surface Wrap to AS3 DisplacementMapFilter

After Effect has the possibility to apply the a Bezier Surface over an image.
However we want to achieve that affect with AS3.
We can use DisplacementMapFilter, using a mapBitmap for each frame for the bezier effect..
How can we generate each of those bitmaps?
The only information that after effect gives are the 12 control points for 12 key frames each one.
How can we with that information generate those mapBitmap that the DisplacementMapFilter operation requests?
Maybe after effect has another information that we are missing?
Thanks in advance.
I'm asuming you're trying to come up with something like this: http://fatlinesofcode.philipandrews.org/2011/02/20/warping-bitmaps-with-a-bezier-surface/
Displacement map filter has limitations that would make this difficult.
The trick is to break up the image into triangles and warp these triangles along the bezier lines/surface you like. The more triangles you use the smoother the resulting image.
this is a good place to start : http://www.flashandmath.com/advanced/p10triangles/index.html
here is a more advanced example (without code) http://www.miaumiau.cat/2010/03/simple-surface-editor/ that is using bezier curves
more code here also: http://wonderfl.net/c/rFOlY
you can try looking up more resources with drawTriangles and distort keywords

AS3 Fisheye Effect

I'm having trouble understand how DisplacementMapFilter works. Basically, I'm trying to create a revolving planet through a combination of fisheye/masking.
Also, how do I go about doing this via timeline? I'm not too familiar with coding within it, but this is more of an animation project than anything else, so classes are out of the question. Sorry for the lack of code -- I'm simply stuck.
As noted in the comments above, this probably only answers half the problem;
Generating a displacement map image isn't too difficult with the right tools. I'll assume you're using Photoshop, GIMP, Fireworks, or similar.
It's probably best to work on a 128x128 image or smaller with this method. Some editors have more specialised tools which let you work on pretty much any size of image, but this is a generic process that needs no special tools. You can always enlarge the end result, but the quality will begin to go down.
Start with a gradient fill. It should go from pure black on the left to dark red on the right (specifically 128,0,0). Add a vertical fill from black at the top to dark green at the bottom (specifically 0,128,0), and combine them with a LIGHTEN or ADD filter. You should now have an image which has black, red, green and yellow corners. Flatten it.
Copy this image to another layer / whatever the term-of-choice is for your editor. Apply whatever displacement filter you want to it (maybe a fish eye, maybe a manual smudge, maybe a perspective transform, anything)
Add a third layer between the two. Flood-fill it with dark yellow (128,128,0) and set it to ADD / ADDITION blend mode. Set the top layer to SUBTRACT / SUBTRACTION blend mode.
That's it. You should get a mostly yellow image which will function as a displacement map.
Update:
To use this in the example program (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filters/DisplacementMapFilter.html#includeExamplesSummary), replace the createBitmapData function with this:
private function createBitmapData():BitmapData {
return myBitmapObject.bitmapData;
}
where myBitmapObject is the instance name (I think) of your displacement Bitmap. There are tidier ways of setting that up, but this is the easiest.

HTML5 Canvas not preserving the draw order

I am trying to draw a rough outline of a building in canvas.
I'm achieving the effect below by creating a series of squares for each side, plus the top 'roof' and then drawing them in sequence basically following the Painter's algorithm.
The screenshot on the left is showing how it should look. This is painting each square separately.
To improve performance I want as few .stroke() and .fill() calls as possible so I queue up all the moveTo() and lineTo() calls and paint them all in one big go.
Tests have shown that (at least for lines) this gives a massive performance improvement and I've verified it myself.
Unfortunately as you can see from the right screenshot, when I paint the buildings only once at the end the layering basically gets destroyed. It paints things in a seemingly random order.
Is the canvas supposed to work this way? Why doesn't it draw everything in the order I told it to draw in like the first screenshot?
Does anyone know a good work around for this behaviour?
If you're sending it all the moveTos and lineTos etc as one big batch, it's going to draw them as if you were rendering one large shape (where you'd want to see all the inner strokes).
There's a minor performance penalty for running multiple draw operations, but it's usually not worth making your code harder to understand and debug.

How can I turn an image file of a game map into boundaries in my program?

I have an image of a basic game map. Think of it as just horizontal and vertical walls which can't be crossed. How can I go from a png image of the walls to something in code easily?
The hard way is pretty straight forward... it's just if I change the image map I would like an easy way to translate that to code.
Thanks!
edit: The map is not tile-based. It's top down 2D.
I dabble in video games, and I personally would not want the hassle of checking the boundaries of pictures on the map. Wouldn't it be cleaner if these walls were objects that just happened to have an image property (or something like it)? The image would display, but the object would have well defined coordinates and a function could decide whether an object was hit every time the player moved.
I need more details.
Is your game tile based? Is it 3d?
If its tile based, you could downsample your image to the tile resolution and then do a 1:1 conversion with each pixel representing a tile.
I suggest writing a script that takes each individual pixel and determines if it represents part of a wall or not (ie black or white). Then, code your game so that walls are built from individual little block, represented by the pixels. Shouldn't be TOO hard...
If you don't need to precompute anything using the map info. You can just check in runtime logic using getPixel(x,y) like function.
Well, i can see two cases with two different "best solution" depending on where your graphic comes from:
Your graphics is tiled, and thus you can easily "recognize" a block because it's using the same graphics as other blocks and all you would have to do is a program that, when given a list of "blocking tiles" and a map can produce a "collision map" by comparing each tile with tiles in the "blocking list".
Your graphics is just some graphics (e.g. it could be a picture, or some CG graphics) and you don't expect pixels for a block to be the same as pixels from another block. You could still try to apply an "edge detection" algorithm on your picture, but my guess is then that you should rather split your picture in a BG layer and a FG layer so that the FG layer has a pre-defined color (or alpha=0) and test pixels against that color to define whether things are blocking or not.
You don't have much blocking shapes, but they are usually complex (polygons, ellipses) and would be unefficient to render using a bitmap of the world or to pack as "tile attributes". This is typically the case for point-and-click adventure games, for instance. In that case, you're probably to create path that match your boundaries with a vector drawing program and dig for a library that does polygon intersection or bezier collisions.
Good luck and have fun.