Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android imageview get pixel color from scaled image

My home automation app has a feature where people can upload images to their phone with floorplans and dashboards that they can use to control their home automation software. I have them upload two images: one visible image with the graphics that they want displayed, and a second color map with solid colors corresponding to the objects they want to target areas from the visible image. Both images have to be the same size, pixel-wise. When they tap the screen, I want to be able to get the color from the colormap overlay, and then I proceed to do what ever action has been associated with that color. The problem is, the scaling of the image is screwing me up. The images that they use can be larger than the device screen, so I scale them so they will fit within the display. I don't really need pinch to zoom capability right now, but I might implement it later. For now, I just want the image to be displayed at the largest size so it fits on the screen. So, my question is, how could I modify this code so that I can get the correct touchpoint color from the scaled image. The image scaling itself seems to be working fine. It is scaled and displays correctly. I just can't get the right touchpoint.

 final Bitmap bm = decodeSampledBitmapFromFile(visible_image, size, size);
 if (bm!=null) {
    imageview.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
    imageview.setImageBitmap(bm);
 }

 final Bitmap bm2 = decodeSampledBitmapFromFile(image_overlay, size, size);
 if (bm2!=null) {
    overlayimageview.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
    overlayimageview.setImageBitmap(bm2);

    imageview.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent mev) {
            DecodeActionDownEvent(v, mev, bm2);
            return false;
        }

    });
 }

 private void DecodeActionDownEvent(View v, MotionEvent ev, Bitmap bm2)
 {
    xCoord = Integer.valueOf((int)ev.getRawX());
    yCoord = Integer.valueOf((int)ev.getRawY());
    try {
        // Here's where the trouble is.
        // returns the value of the unscaled pixel at the scaled touch point?
        colorTouched = bm2.getPixel(xCoord, yCoord); 
    } catch (IllegalArgumentException e) {
        colorTouched = Color.WHITE; // nothing happens when touching white
    }
 }

 private static Bitmap decodeSampledBitmapFromFile(String fileName, 
         int reqWidth, int reqHeight) {
     // code from 
     // http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
     final BitmapFactory.Options options = new BitmapFactory.Options();
     options.inJustDecodeBounds = true;
     BitmapFactory.decodeFile(fileName, options);

     // Calculate inSampleSize
     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

     // Decode bitmap with inSampleSize set
     options.inJustDecodeBounds = false;
     return BitmapFactory.decodeFile(fileName, options);
 }

 private static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) {
     // code from 
     // http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
     // Raw height and width of image
     final int height = options.outHeight;
     final int width = options.outWidth;
     int inSampleSize = 1;

     if (height > reqHeight || width > reqWidth) {
       if (width > height) {
          inSampleSize = Math.round((float)height / (float)reqHeight);
       } else {
          inSampleSize = Math.round((float)width / (float)reqWidth);
       }
     }
     return inSampleSize;
 }
like image 636
MrGibbage Avatar asked Sep 19 '12 13:09

MrGibbage


1 Answers

I figured it out. I replaced

 xCoord = Integer.valueOf((int)ev.getRawX());
 yCoord = Integer.valueOf((int)ev.getRawY());

with

 Matrix inverse = new Matrix();
 v.getImageMatrix().invert(inverse);
 float[] touchPoint = new float[] {ev.getX(), ev.getY()};
 inverse.mapPoints(touchPoint);
 xCoord = Integer.valueOf((int)touchPoint[0]);
 yCoord = Integer.valueOf((int)touchPoint[1]);
like image 176
MrGibbage Avatar answered Nov 29 '22 13:11

MrGibbage