2

I am currently using the below code as a basis for image-mapping on Android.

The code works by having a invisible mask of an image with various coloured "hotspots".

enter image description here

It then uses an OnTouchListener to determine the colour the user has touched, changing the image in doing so e.g. red = image_1, blue = image_2 etc.

The provided code works great and has been a ideal stepping stone for my scenario, however it only allows the user to display one part of the image such as the alien or flames.

enter image description here

I was wondering if it is possible to display multiple parts of the image map at the same time (Alien & Flames). Sorry if this post has been formatted weird (First time posting)

ColourTool:

package com.wglxy.example.imageareas;

import android.graphics.Color;

/**
 * A class with methods to help with colors.
 * (Only one method so far.)
 * 
 */

public class ColorTool {

/**
 * Return true if the two colors are a pretty good match.
 * To be a good match, all three color values (RGB) must be within the tolerance value given.
 * 
 * @param color1 int
 * @param color2 int
 * @param tolerance int - the max difference that is allowed for any of the RGB components
 * @return boolean
 */

public boolean closeMatch (int color1, int color2, int tolerance) {
    if ((int) Math.abs (Color.red (color1) - Color.red (color2)) > tolerance ) return false;
    if ((int) Math.abs (Color.green (color1) - Color.green (color2)) > tolerance ) return false;
    if ((int) Math.abs (Color.blue (color1) - Color.blue (color2)) > tolerance ) return false;
    return true;
} // end match

} // end class

ImageAreasActivity:

package com.wglxy.example.imageareas;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * This activity displays an image on the screen. 
 * The image has three different regions that can be clicked / touched.
 * When a region is touched, the activity changes the view to show a different
 * image.
 *
 */

public class ImageAreasActivity extends Activity 
    implements View.OnTouchListener 
{

/**
 * Create the view for the activity.
 *tt
 */

@Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ImageView iv = (ImageView) findViewById (R.id.image);
    if (iv != null) {
       iv.setOnTouchListener (this);
    }

    toast ("Touch the screen to discover where the regions are.");
}

/**
 * Respond to the user touching the screen.
 * Change images to make things appear and disappear from the screen.
 *
 */    

public boolean onTouch (View v, MotionEvent ev) 
{
    boolean handledHere = false;

    final int action = ev.getAction();

    final int evX = (int) ev.getX();
    final int evY = (int) ev.getY();
    int nextImage = -1;         // resource id of the next image to display

    // If we cannot find the imageView, return.
    ImageView imageView = (ImageView) v.findViewById (R.id.image);
    if (imageView == null) return false;

    // When the action is Down, see if we should show the "pressed" image for the default image.
    // We do this when the default image is showing. That condition is detectable by looking at the
    // tag of the view. If it is null or contains the resource number of the default image, display the pressed image.
    Integer tagNum = (Integer) imageView.getTag ();
    int currentResource = (tagNum == null) ? R.drawable.p2_ship_default : tagNum.intValue ();

    // Now that we know the current resource being displayed we can handle the DOWN and UP events.

    switch (action) {
    case MotionEvent.ACTION_DOWN :
       if (currentResource == R.drawable.p2_ship_default) {
          nextImage = R.drawable.p2_ship_pressed;
          handledHere = true;
       /*
       } else if (currentResource != R.drawable.p2_ship_default) {
         nextImage = R.drawable.p2_ship_default;
         handledHere = true;
       */
       } else handledHere = true;
       break;

    case MotionEvent.ACTION_UP :
       // On the UP, we do the click action.
       // The hidden image (image_areas) has three different hotspots on it.
       // The colors are red, blue, and yellow.
       // Use image_areas to determine which region the user touched.
       int touchColor = getHotspotColor (R.id.image_areas, evX, evY);

       // Compare the touchColor to the expected values. Switch C to a different image, depending on what color was touched.
       // Note that we use a Color Tool object to test whether the observed color is close enough to the real color to
       // count as a match. We do this because colors on the screen do not match the map exactly because of scaling and
       // varying pixel density.
       ColorTool ct = new ColorTool ();;
       int tolerance = 25;
       nextImage = R.drawable.p2_ship_default;
       if (ct.closeMatch (Color.RED, touchColor, tolerance)) nextImage = R.drawable.p2_ship_alien;
       else if (ct.closeMatch (Color.BLUE, touchColor, tolerance)) nextImage = R.drawable.p2_ship_powered;
       else if (ct.closeMatch (Color.YELLOW, touchColor, tolerance)) nextImage = R.drawable.p2_ship_no_star;
       else if (ct.closeMatch (Color.WHITE, touchColor, tolerance)) nextImage = R.drawable.p2_ship_default;


       // toast ("Current image: " + currentResource + " next: " + nextImage);
       if (currentResource == nextImage) {
          nextImage = R.drawable.p2_ship_default;
       } 
       handledHere = true; 
       break;

    default:
       handledHere = false;
    } // end switch

    if (handledHere) {

       if (nextImage > 0) {
          imageView.setImageResource (nextImage);
          imageView.setTag (nextImage);
       }
    }
    return handledHere;
}   

/**
 * Resume the activity.
 */

@Override protected void onResume() {
    super.onResume();

    View v  = findViewById (R.id.wglxy_bar);
    if (v != null) {
       Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
       //anim1.setAnimationListener (new StartActivityAfterAnimation (i));
       v.startAnimation (anim1);
    }
}

/**
 * Handle a click on the Wglxy views at the bottom.
 *
 */    

public void onClickWglxy (View v) {
    Intent viewIntent = new Intent ("android.intent.action.VIEW", 
                                    Uri.parse("http://double-star.appspot.com/blahti/ds-download.html"));
    startActivity(viewIntent);

}


/**
 */
// More methods

/**
 * Get the color from the hotspot image at point x-y.
 * 
 */

public int getHotspotColor (int hotspotId, int x, int y) {
    ImageView img = (ImageView) findViewById (hotspotId);
    if (img == null) {
       Log.d ("ImageAreasActivity", "Hot spot image not found");
       return 0;
    } else {
      img.setDrawingCacheEnabled(true); 
      Bitmap hotspots = Bitmap.createBitmap(img.getDrawingCache()); 
      if (hotspots == null) {
         Log.d ("ImageAreasActivity", "Hot spot bitmap was not created");
         return 0;
      } else {
        img.setDrawingCacheEnabled(false);
        return hotspots.getPixel(x, y);
      }
    }
}

/**
 * Show a string on the screen via Toast.
 * 
 * @param msg String
 * @return void
 */

public void toast (String msg)
{
    Toast.makeText (getApplicationContext(), msg, Toast.LENGTH_LONG).show ();
} // end toast

} // end class
Vishal Senjaliya
  • 454
  • 6
  • 21
Calvin-Castle
  • 111
  • 1
  • 8
  • Original Tutorial: https://blahti.wordpress.com/2012/06/26/images-with-clickable-areas/ – Calvin-Castle Jun 03 '17 at 00:02
  • Progress: I have created transparent versions of each asset (Aliens, Flames...) set them to "Invisible" and then on (if (ct.closeMatch (Color.RED, touchColor, tolerance))) set them to "Visible" but I do not know how to fix the loop allowing the user to click the same asset to remove it like before. Thanks. – Calvin-Castle Jun 03 '17 at 01:31

0 Answers0