generic drugs from india

ImageMap for Android

Update September 12 2013

I have disable comments for this post. I am amazed that this old code is still getting so much attention. I feel that the code has become dated and needs a good refactoring. It needs to be tested with newer version of android SDKs. The touch handling needs to be cleaned up. If you find yourself still compelled to use this code, and you have questions/issues, PLEASE direct them to the GITHUB issues list for the project.

Update March 6 2013

Thank you for all of the interest in this widget.

I have become a bit overloaded with work in recent months and I have regrettably been unable to reply to comments in anything near a timely manner.

If you have a question about features or have run into a shortcoming or bug in this widget, I am recommending that you open an issue on GitHub.

This will provide me a better way of tracking problems and questions and may enable you to get help from other people who have used/forked the repo.

As my time frees up (hopefully) I will do my best to create examples and fix bugs. This widget is really due for a hard core refactoring.

- original post -

I found myself needing to display an image and have the user tap on different parts of the image to navigate and perform actions.  After sketching out what I needed, it became apparent that what I wanted was something like an HTML map tag, but in an Android view.  A bit more thinking and I decided this would be a useful widget to have available.

The resulting code:

  • Supports images as drawable or bitmap in layout
  • Allows for a list of area tags in xml
  • Enables use of cut and paste HTML area tags to a resource xml  (ie, the ability to take an HTML map and image and use it with minimal editing)
  • Supports panning if the image is larger than the device screen
  • Supports pinch-zoom
  • Supports callbacks when an area is tapped.
  • Supports showing annotations as bubble text and provide callback if the bubble is tapped

The code can be found in GitHub – Android Image Map

Update 2 March 2012: Added an option to always resize the image using the original image bits. Certain images, when resized up and down lose a lot of their image quality. Always resizing from the original bits gives the best possible image, but requires extra memory. The tradeoff is now up to you.

Here are some quick notes about the implementation, I’ll make some follow up posts with more details about some of the key areas.

The ease of associating the map with the img matches the ease of doing so in an img tag in HTML.  Just supply the name of the map to use in the layout:

<!--?xml version="1.0" encoding="utf-8"?-->

The area map is specified in your project at res/xml/map.xml
One difference over HTML maps is that each area must have an id. I went back and forth on this requirement, and I may change the code to allow for areas without id. The code will use the name attribute if present, otherwise it will look for title or alt. The current implementation also requires a name for each area, though this could be changed easily.

<!--?xml version="1.0" encoding="utf-8"?-->
<maps xmlns:android="">
    <map name="gridmap">
        <area id="@+id/area1001" shape="rect" coords="118,124,219,226" />
        <area id="@+id/area1002" shape="rect" coords="474,374,574,476" />
        <area id="@+id/area1004" shape="rect" coords="710,878,808,980" />
        <area id="@+id/area1005" shape="circle" coords="574,214,74" />
        <area id="@+id/area1006" shape="poly" coords="250,780,250,951,405,951" />
        <area id="@+id/area1007" shape="poly" coords="592,502,592,730,808,730,808,502,709,502,709,603,690,603,690,502" />
    <map name="usamap">
		<area id="@+id/area1" shape="poly" coords="230,35,294,38,299,57,299,79,228,79" />

The image itself is placed in res/drawable-nodpi so that the system will not attempt to fit the image to the device based on dpi. This way we are guaranteed that our area coordinates will map properly to the displayed image.

Here is a sample activity that finds the view in the layout and adds an on click handler

public class ImageMapTestActivity extends Activity {
	ImageMap mImageMap;

    public void onCreate(Bundle savedInstanceState) {

        // find the image map in the view
        mImageMap = (ImageMap)findViewById(;

        // add a click handler to react when areas are tapped
        mImageMap.addOnImageMapClickedHandler(new ImageMap.OnImageMapClickedHandler() {
			public void onImageMapClicked(int id) {
				// when the area is tapped, show the name in a
				// text bubble

			public void onBubbleClicked(int id) {
				// react to info bubble for area being tapped

There were lots of challenges with this view. I’ll post some follow up thoughts over the next few days along with a bit of discussion about the implementation.

Enjoy the code!

Leave a comment ?


  1. Thanks, this was very helpful. I was able to adapt it for some seating charts.

    I’m using it inside a fragment in api 12. I had to comment out one line to get around a recycled image error when the image is created a second time.


  2. Hi Im trying to implement this into my class project but am unable to figure what this does in the main.xml


    When i use your classes in my app, what do I change ctc: to since I cannot use your package name?
    This might be a silly question but I hope you answer it.

    • ctc is an arbitrary name given to this app’s local attribute namespace.

      Look at this line at the top of the main.xml layout


      This indicates that any attributes from the attr.xml in should be referred to with the namespace ctc.

      You can change this to any name you’d like.



      Hope that helps.

      • Sorry for the late response.

        I figured it out on my own after a day or two of posting this and forgot about the comment.

        Thanks anyways for the reply
        This ImageMap has greatly helped me.


  3. Hi, first of all, sorry for my bad english.
    i’m a newbie in the world of android developing.
    I have an image and i have already mapped it. I have changed mail.xml and maps.xml. In the application i can only see (and pinch) my image, if i tap on the areas of the image, it happens nothing.

    Do i have to change something in the java file

    Thanks a lot in advance!

  4. Because i have found that the width of the scroll area is like the width of the view. i would that the scrollable area is as large as the image.

  5. Hi, first of all thanx for such a great tutorial.
    very near to what i am searching.
    can you plz help me, i want some hover image over the area of country i have clicked for ex. suppose i clicked on California it should change the color of California in image on click and again should come in the original color when dropping the click…sorry for bad English but hope you understand what i want .plz reply asap!

  6. Good piece of code!

    I have a large image cropped into tiles. Is it possible to load them and form the complete image and add maps for each one with your code?

    Thank you very much!

    • Hi Eduardo.

      The goal of this project was to closely match the html imagemap for single images and one list of areas. As such I didn’t dive into the complexity of managing more than one image.

      I have been wanting to support multiple/split images and have just not had the time. If I do manage to find the time and code it up, I’ll post about it here. I just don’t want to make any promises.

  7. Great job with the image maps. Just a quick question, would this work for images that are scaled to different proportions? IE let’s say I have a 600×400 image, and I stretch it to 100% each way on phones and tablets, would your class be able to handle it?

    • The current version in github forces the aspect ratio of the image to be retained.

      I have a new version that optionally supports resizing of the image to fill the view disregarding aspect ratio. I will clean up this code and push it a bit later today.

    • I just pushed an update to github that supports the “make the image fill the view” use case.

  8. Anyone run into the following visual issues on pinch zooming the graphic. Each time the graphic is zoomed in and out, it appears the lines are losing their sharpness and making the graphic blurry to view. I’m trying to implement using picture of a map, and on Pinch Zoom, the graphic becomes unreadable.

    • Yes. I am attempting to use as little memory as possible, so the code resizes the current image over and over and could lose quality over time.

      To maintain better quality you will want to change the code so that it keeps the original image and uses those original bits in the call to createScaledBitmap. This requires more memory, but should result in better quality.

      I will work that change up later today and post new code.

      • Scott.. that’s the direction I’m getting when asking around in IRC. This is a solid and comprehensive solution that you’ve posted, I can’t find anything that matches it as most devs want to keep from using the old ImageMap concept, but in my case, I have to use it. Thanks for your help.

      • Interesting, I tweaked your scaleBitmap method to create a new instance of the bitmap graphic, still getting blurry graphic when zooming in and out:

        mExpandWidth = mImage.getWidth();
        mExpandHeight = mImage.getHeight();

        mResizeFactorX = ((float) newWidth) / mExpandWidth;
        mResizeFactorY = ((float) newHeight) / mExpandHeight;

        // create a matrix for the manipulation
        Matrix matrix = new Matrix();

        // resize the bit map
        matrix.postScale(mResizeFactorX, mResizeFactorY);

        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(mImage, 0, 0, mExpandWidth, mExpandHeight, matrix, true);

        mImage = resizedBitmap;

        mRightBound = mExpandWidth>mViewWidth ? 0 – (mExpandWidth – mViewWidth) : 0;
        mBottomBound = mExpandHeight>mViewHeight ? 0 – (mExpandHeight – mViewHeight) : 0;

        • I pushed new code to github that adds support to always resize from the original image bits. In my testing this improves the quality when zooming in and out.

  9. Ok so I’ve tried it, and I have to admit it’s pretty good. The touch doesn’t seem as sensitive as I was hoping or maybe I’m defining my points too small. The other question is, how hard would it be for you to add borders so that we can see the points as defined on the map?

    • Hi Waseem

      If you are using polygons as the areas, there is some code (commented out) that will draw the bounding box of the polygon. Search for “bounding box” and remove the comments around the onDraw method.

      You could add a similar method to the Rect and Circle area types pretty easily.

      As for performance, I agree. There is some sluggishness. I hope to free up some time to be able to dig into that deeper. For the application I was using this for, the performance was acceptable, but I have seen other cases where it is not.

  10. Hi Scott,

    I’m having problems with the loss of image quality when pich to zoom. I’m trying to change the code, but so far I have not succeeded. Could you help me?

    • Hi Philipe, I just pushed some new code to github that supports optionally always using the original image for resizing. This should improve the loss of image quality.

  11. Hi Scott,

    Really good code, it works great!

    I just have one question. How/where would I implement support for handling long tapping on the map?

    • Osvald. Apologies for not answering this sooner.

      The touch handling in this example is old and needs a nice update. Here is how I would approach long press.

      In onTouchDown when a touch is started, keep the start time for the touch point (System.currentTimeMillis())

      start a timer

      when the timer reaches the duration you want for long press, check the touch points to see if any are down and have not moved. That is a long press.

      In onTouchMoved reset the time for the touchpoint so that moving a point does not result in long press

      If I get more free time I plan to detach the touch handler from the widget and add long press. Also, I’d like to be able to swap in a different touch handler (there are some good ones on github).

      I know that’s not the best answer, but there you have it. Hope that helps.

  12. Hey Scott,

    awesome code you have there, thanks so much.
    I need some help though if you don’t mind.
    I’m working with SDKVersion 15 and R.stylable was taken out of the SDK because apparently they were device specific.

    How do I work around R.stylable? I’m completely stuck..

  13. Hello,

    Nice piece of code, I haven’t tried it out yet. I wanted to know if this code can be used without any copyright violations. Please let me know.


  14. Hello,

    I am having trouble compiling the codes. I changed the package name to my own as stated and left everything else the same. Renamed the res/layout/main.xml with a different name and did the same directory structure for both maps.xml and attrs.xml (in XML and values folder).

    // find the image map in the view
    mImageMap = (ImageMap)findViewById(;

    I get an error message on this line stating “cannot cast View to ImageMap”

    Please help me out. thanks many.

    • If you have the ImageMap class and your test activity in different packages, you will have to import the ImageMap class.

  15. I have implemented your code properly! but my image map do anything!

    When i touch the mapped areas! any ideas?

    • HI Spiros. The main things to check.

      Did your map get loaded from xml.
      Put a breakpoint in the loadMap method and step through to make sure.

      Are your areas large enough for a tap? If the area is too small it may be impossible to tap.

      If you are using POLY areas, enable the code that draws the bounding box around the polygon. This draw a box on the image showing the area boundaries. This is often helpful. Search for “bounding box for the polygons” and uncomment the code there.

      If you are using

  16. Hi everybody,

    I’m trying to create a new project based on the source code.
    When creating a the attrs.xml file based on the example, i’m getting the following code in the R class:

    public static final class attr {
    /** Must be a string value, using ‘\\;’ to escape characters such as ‘\\n’ or ‘\\uxxxx’ for a unicode character.
    This may also be a reference to a resource (in the form
    @[package:]type:name“) or
    theme attribute (in the form
    containing a value of this type.
    public static final int map=0x7f010000;

    I need this to work correctly, so I can do the correct reference in the loadAttributes() method from the ImageMap class.

    Thank you everybody.

  17. Hey I’m not even sure how to add this as a widget that I can use. Can somebody help or link me to a tutorial. Sorry if this is a little simple I just have no idea. :/

    • Hi Jake. When I have more time I will write up more of a “How to use this” post. Sorry I can’t be more helpful right now.

  18. thanks for the code at first,

    it works, but i got out of memory exception when i loaded image from xml.

    when i loaded image from code like mImageMap.setImageBitmap(img), the image was loaded, but it did not react.

    please help me, thanks!

    • How big of an image are you using? I can’t think of any obvious reason loading from XML would cause memory problems vs loading in code.

  19. Hey, I tried to add my map into the maps.xml file and set the id like area101, area102 etc. However the generated file does not include these ids by itself. Should I add them myself?

    • In android programming you should NEVER attempt to add anything to by hand. This file will be deleted and regenerated frequently.

      The resource compiler should manage your IDs just like any other xml. For example, in map.xml for the US states map I use

  20. Paulo Carabuena

    hi. thus this work when android resize the image? I mean the coordinates in your code are hard-coded right? IT would mess up the image map, right?

    • Hi Paulo

      The code support image resize. The touch handler scales the coordinates properly so that hit test on areas works properly. See the onScreenTapped method

      // adjust for x y resize
      testx = (int)((float)testx/mResizeFactorX);
      testy = (int)((float)testy/mResizeFactorY);

  21. Hi, I’m trying to work with imagemap AndroidImageMap. I need to plot the bubbles initially when the activity starts. I have tried by iterating the ‘mIdToArea’ and plotting in oncreate of the activity. But the bubbles are not showing. I used mImagemap.invalidate() code too. I’m calling the following methods after iterating the values.

    mImageMap.onScreenTapped(x, y);
    mImageMap.centerArea( key );
    But the bubbles are not displaying by default when the activity is created.

    • A couple things.

      First, showBubble is set up to only show one bubble at a time. Each time showBubble is called it clears the current bubble list then only shows the one you are calling it for.

      Beyond that I would put a breakpoint in showBubble and make sure that the key you are passing in is matching an area.

      • Hi, I have tried and first time on loading the image, the ‘onSizeChanged’ method is not called and so the ‘mViewHeight’ and ‘mViewWidth’ remains -1 till any click event occurs. how to set the screen size so that i’m calling the showbubble method in onCreate(), it will call the ‘onSizeChanged’ method

  22. I have been looking for this for the past month. I am gonna start looking in more details into this. Because I have a Square shape venn diagram and I want each of its areas can be clickable. Just one question Scott, can my image be zoomable and this still work ? Please say yes :cry:

  23. It works really well, I just need to know how can I dynamically change the name tags that are created in the bubble ? I can do this from xml/maps.xml file by changing area name, but I want to do this during the run time based using some IF condition I have. I am really looking forward to your answer. Thanks

    • Quick way would be to use ImageMap.showBubble(“some text”, id); instead of ImageMap.showBubble(id);

      If you need to access the area name or want to change the area name you will have to do a bit more work.
      One way would be to make the Area class public and add a method to ImageMap that returns the Area based on Id.

      public Area getArea(int areaId) {
      Area a = mIdToArea.get(areaId);
      return a;

      Then you can get at the Area and do whatever you want.

  24. Hi!
    I hope you are still following on this thread.
    First of all, great work on your widget, i’ve been looking for something like this for months.
    Few questions on implementation though..
    First, when I tried to port my html functionning map in your widget, I noticed coordinates were innacurate. Only in the top left corner, without scaling of any sort. Am I doing something wrong? I’m using the widget inside of a fragment, inside of a TabActivity. Could this be the problem?
    So, to debug, I tried to draw the polygons. Looking at your code, it looks like you’re making rectangle from those polygons. Is it the way you designed the widget? If so, I cannot use it… :/

    • Polygon areas use a polygon hit test. See class PolyArea IsInArea. The algorithm comes from

      The debug code in the onDraw for PolyArea just shows the bounding box for the polygons to gives a quick idea if the polys are in the right location.

      Here is a version of the PolyArea onDraw that would draw the polygon completely.

      public void onDraw(Canvas canvas) {	
      			// draw the full polygon
      			Path polyPath = new Path();
      			polyPath.moveTo(xpoints.get(0)* mResizeFactorX + mScrollLeft, ypoints.get(0)* mResizeFactorY + mScrollTop);
      			for (int i = 1; i < _points; i++) {
      				polyPath.lineTo(xpoints.get(i)* mResizeFactorX + mScrollLeft, ypoints.get(i)* mResizeFactorY + mScrollTop);
      			polyPath.lineTo(xpoints.get(0)* mResizeFactorX + mScrollLeft, ypoints.get(0)* mResizeFactorY + mScrollTop);
      			canvas.drawPath(polyPath, textOutlinePaint);

      I have not used this in a Fragment in a TabActivity. If I get a chance I’ll give it a try and see. Someone else mentioned some kind of issue being embedded in a Fragment.

  25. How can i get the coordinates of each part of the image
    My image is a seat map of a bus.So for each seat I need the coords.If my image already contains the seats ,then how would i use it in your app.Do i need to use the plain image w/o seats? Please help me

    • This widget is designed to act like an HTML imageMap. To use it you provide the image (in your case with the seats) and a list of all of the areas. If you don’t already have a list of the area coordinates you will have to either build on by hand or find an imageMap tool that helps.

  26. Thank you! You saved me a couple of weeks!!! Great code and does exactly what I needed it to do! I struggled with this for weeks!

    • I also have a question. Everything is working great but the text bubble is not centered in rectangles, is there a way to fix that? It shows on the upper right of the rectangle and not in the center of it.


      • In order to get the bubbles for rectangle to appear in the center, modify the following code in the RectArea class.

        public float getOriginX() {
        return _left + (_right-_left)/2;

        public float getOriginY() {
        return _top + (_bottom-_top)/2;

  27. Thanks this will save me a weeks work :razz: I hope to share stuff like this in the future.

    Gideon Bar

  28. hi,
    its working, super,
    I developed a application using html in android phonegap. Can u tell me how to use image map in android html page.

    • If you want to display an html page, I would just use a WebView and an actual html imagemap. This widget is for cases where I didn’t want to use a full WebView, but I wanted image map like behavior.

  29. thank you very much this is exactly what i want but i have an error in ImageMapTestActivity Class

    The method onImageMapClicked(int) of type new ImageMap.OnImageMapClickedHandler(){} must override a superclass method

    on both onImageMapClicked and onBubbleClicked methods

  30. Hi Scott, congrats for your widget that seems to be the only reference so far. I’m using it inserted in a fragment, it works fine except for resizing down, more precisely it doesn’t react to android:layout_ as “wrap_content” in mail.xml. Am I wrong or you didn’t implement that? In this case I have to create my image file on the exact container proportions. If you have time please drop a hint about that. Thanks

  31. never mind ive solved it…………

    but i have another question
    can i make a picture come out when i press on the bubble
    or at the specific place without the bubble

  32. Hello Scott! Thank you so much for creating this widget. It was very useful. I’ve been working with it for the past few days and out of everything, I have only one problem I’d like you to help me with. If you still check for comments on this article, that is.

    So, everything works fine, as intended, except one thing. I’m unable to dynamically add bitmaps to area objects created in ImageMap. Not only that, I was unable to display any bitmap on screen in any way, even hardcoding it in. What advice would you give in order to display a simple picture over an area (RectArea in this case) and how would I be able to add it in? Anything may help, if I manage to display any picture over the area, I could work from there. Thank you!

    • I managed to find my mistake. For debugging purposes, I mistakenly left the onDraw method in RectArea that draws a border. That removed the original result.

      My problem now is that bitmaps loaded do not resize while pinch zooming. Could you tell what could I do to fix this issue?

      • The main image bitmap does not resize? Or are these other bitmaps?

        • Hi, Scott! Sorry for not being clear. Main image does resize, but I’m placing bitmap images for every area I define in xml. I use the setBitmap method inside abstract class Area. While zooming in and out, it does not resize, it is only keeping it’s original size.

          Any advice would help. Thank you again for this awesome widget!

  33. Hi
    I have run the example activity with the demo data, and even my own custom image and touchable coordinates and it works well.
    Now I want to be able to change the image and coordinates programmatically, so when a user chooses an image from a list it loads the png and coord map associated with the selection:

    something like:
    User clicks Australia
    String mapName = “australia”;
    imageMap.setImageResource(mapName + “.png”);

    Thanks in advance.

  34. Thanks very much for this code. Do you have a paypal donations page?

    Also, any idea if there is a simple way to determine the countries/areas that border an area clicked on?

  35. Nice job making this Scott and thanks for sharing!

    I would like if it was possible to make my layout so i had label at top, then the imagemap below that.
    The imagemap should scale so it matches the space available below the label above it but keeps it dimensions.
    so there might be space at top and bottom of the imagemap or left or right of the imagemap depending on the screen size.

    Is that in any way possible to do that?

    • ImageMap is used just like any kind of view inside a of layout. Just add your other views around it.

      If I find some time later I’ll add example code.

  36. Hi,this is very nice concept..

  37. when we zoom the image , the image size get wider, here what i want is when we click at the corner of the layout where we applied the hotspot , it should move towards left or right so that bubble message can readed properly and doesn’t get cut off.
    As this king of concept i have seen android map ,if we click on any location which is in the corner , it slide little bit.

    Can you plz help for it..

  38. Hi, thanks for the widget. It is really cool.

    I am having a couple of problems though. I have my map widget inside a viewpager, and when pinching for zoom, I get a ConcurrentModificationException error.

    Anyway, I don’t need zoom, I would like my images to be downscaled to fit the view, but keeping aspect ratio, is this possible?

    • Well I partially solved the aspect ratio thing with this code:

      * setInitialImageBoundsFitImage sets the initial image size to match the
      * screen size. aspect ratio may be broken
      void setInitialImageBoundsFitImageKeepAspectRatio() {
      if (mImage != null) {
      float aspect = mImage.getWidth() / mImage.getHeight();
      mMinHeight = mViewHeight;
      mMinWidth = (int) (aspect * mMinHeight);
      else {
      mMinWidth = mViewWidth;
      mMinHeight = (int) (mMinWidth / aspect);

      mMaxWidth = (int) (mMinWidth * mMaxSize);
      mMaxHeight = (int) (mMinHeight * mMaxSize);
      mScrollTop = 0;
      mScrollLeft = 0;
      scaleBitmap(mMinWidth, mMinHeight);

      But the image is shown on top of the imageview. I would like it to be shown in the center. Is this possible?

  39. I would also need to load resources (both maps and images) from sdcard, but if I manually create the ImageMap object then the size for the view is set to -1 and thus the program crashes. How do I calculate this size in the constructor?

  40. I need to plot the bubbles initially when the activity starts.

  41. Hi,

    first – thanks for great widget it solves a lots of challenges regarding image maps. I have one more problem to be solved, and I wanted to share some of my thoughts. Besides showing a map with regions (fair booth plan), a need to draw – fill a booth (region) that is already defined in image map. This is a part of functionality to show position of booth in map (fill a region with different colour). Im thinking about canvas.drawBitmap where canvas is image map. Maybe you could put method that will do this…

    Best regards,


  42. hi
    is there any way to prevent dragging image after it reaches the border…?

  43. Hi everyone.

    Thanks for all of the interest in this widget.

    I have become a bit overloaded with work in recent months and I have regrettably been unable to reply to comments in anything near a timely manner.

    If you have a question about features or have run into a shortcoming or bug in this widget, I am recommending that you open an issue on GitHub.

    This will provide me a better way of tracking problems and questions and may enable you to get help from other people who have used/forked the repo.

    As my time frees up (hopefully) I will do my best to create examples and fix bugs. This widget is really due for a hard core refactoring.

  44. Thanks! This worked really well for me. I followed your directions and was able to switch out the image and make a new map in less than an hour (I’ve only been studying a bit of android for a month or two, total beginner with programming) Thanks again!

  45. First of all, thanks for the widget, it’s saved me loads of time!
    Is there any way of including an image in the popup (as well as text?) and what is the best way of styling the popup?
    Thanks in advance

    • The entire popup including the text is drawn directly to the canvas in the onDraw method of Class Bubble.

      You can add any kind of drawing you want here, including adding images.

      A far more complete (and complex) solution which would address a lot of other needs would be to change the popup content to be rendered using a separate view that could be defined in layout XML. Then it would work much like a BaseAdapter getView.

  46. hi,
    please reply to this message….according to your project of github image map the zooming is performed from a side of the corner so i would like to request you please can it be possible for showing pinch zoom effect with center focused zoom in your github project.

    my no:(91)9903076025

  47. Hi,Its a very nice code. I have noticed the only zooming to the right bottom side keeping left top side fixed. Would it be possible to zoom the image all side. And I want to zoom the image on double tap; could you please help me.
    Thanks in advance.

  48. Hello how can i place an intent on these buttons? help. if possible


    I used this to implement the very same project I am not even able to import this project in my eclipse. Can someone help me