Tuesday, October 9, 2012

Get touched pixel color of scaled ImageView

To get touched pixel color of a ImageView, you can implement OnTouchListener of the ImageView, get touched position by calling event.getX() and event.getY(), and get the pixel color by calling bitmap.getPixel(x, y)...IF THE BITMAP IN YOUR ImageView IS DISPLAY AT 1:1, layout_width and layout_height ="wrap_content".

If your bitmap is scaled, such as layout_width and layout_height ="match_parent". It will not work! It's a example demonstrate how to invert the touched position to get pixel from scaled ImageView.

Get touched pixel color of scaled ImageView


package com.example.androidtouchedpixel;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {
 
 TextView touchedXY, invertedXY, imgSize, colorRGB;
 ImageView imgSource1, imgSource2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        touchedXY = (TextView)findViewById(R.id.xy);
        invertedXY = (TextView)findViewById(R.id.invertedxy);
        imgSize = (TextView)findViewById(R.id.size);
        colorRGB = (TextView)findViewById(R.id.colorrgb);
     imgSource1 = (ImageView)findViewById(R.id.source1);
     imgSource2 = (ImageView)findViewById(R.id.source2);
     
     imgSource1.setOnTouchListener(imgSourceOnTouchListener);
     imgSource2.setOnTouchListener(imgSourceOnTouchListener);
     
    }
    
    OnTouchListener imgSourceOnTouchListener
    = new OnTouchListener(){

  @Override
  public boolean onTouch(View view, MotionEvent event) {
   
   float eventX = event.getX();
   float eventY = event.getY();
   float[] eventXY = new float[] {eventX, eventY};
   
   Matrix invertMatrix = new Matrix();
   ((ImageView)view).getImageMatrix().invert(invertMatrix);
   
   invertMatrix.mapPoints(eventXY);
   int x = Integer.valueOf((int)eventXY[0]);
   int y = Integer.valueOf((int)eventXY[1]);
   
   touchedXY.setText(
     "touched position: "
     + String.valueOf(eventX) + " / " 
     + String.valueOf(eventY));
   invertedXY.setText(
     "touched position: "
     + String.valueOf(x) + " / " 
     + String.valueOf(y));

   Drawable imgDrawable = ((ImageView)view).getDrawable();
   Bitmap bitmap = ((BitmapDrawable)imgDrawable).getBitmap();
   
   imgSize.setText(
     "drawable size: "
     + String.valueOf(bitmap.getWidth()) + " / " 
     + String.valueOf(bitmap.getHeight()));
   
   //Limit x, y range within bitmap
   if(x < 0){
    x = 0;
   }else if(x > bitmap.getWidth()-1){
    x = bitmap.getWidth()-1;
   }
   
   if(y < 0){
    y = 0;
   }else if(y > bitmap.getHeight()-1){
    y = bitmap.getHeight()-1;
   }

   int touchedRGB = bitmap.getPixel(x, y);
   
   colorRGB.setText("touched color: " + "#" + Integer.toHexString(touchedRGB));
   colorRGB.setTextColor(touchedRGB);
   
   return true;
  }};

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        tools:context=".MainActivity" />
    <TextView 
        android:id="@+id/xy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="touched position: "/>
    <TextView 
        android:id="@+id/invertedxy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="inverted touched position: "/>
    <TextView 
        android:id="@+id/size"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="drawable size: "/>
    <TextView 
        android:id="@+id/colorrgb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="touched color: "/>
    <ImageView
        android:id="@+id/source1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"/>
    <ImageView
        android:id="@+id/source2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/ic_launcher"/>

</LinearLayout>


download filesDownload the files.


12 comments:

  1. how can i get pixel frame of image from camera

    ReplyDelete
  2. Thanks really very very useful for me

    ReplyDelete
  3. Nice Post !
    Thank you.
    You're doin well ! keep it up

    (y)

    ReplyDelete

  4. Thank you very very much! you save my life!

    ReplyDelete
  5. On API 19 I am not able to use the Matrix function. Do you know an alternative for that?

    ReplyDelete
  6. hello João Augusto,

    API 19 cannot use Matrix? which function?

    ReplyDelete
  7. Hello Eric,

    When I tried to use the command:

    Matrix invertMatrix = new Matrix();

    I was getting an error "Matrix is deprecated" but after I changed my minSdkVersion to 21 it seems to be fixed.

    Thanks. Great Code by the way!

    ReplyDelete
  8. Hello João Augusto,

    Which Matrix you include? android.opengl.Matrix? (http://developer.android.com/reference/android/opengl/Matrix.html#Matrix())

    What I include is android.graphics.Matrix (http://developer.android.com/reference/android/graphics/Matrix.html#Matrix()).

    Try to change your include statement.

    ReplyDelete
  9. Thanks aloot ,I am a developer,It help me alot to complete my project

    ReplyDelete
  10. Thanks man!!! 2016 and works like a charm!!

    ReplyDelete
  11. Hi,

    Thanks for the above post, however I am trying the same code to pick a color from an image at the touched position. It is not picking the same color at the touched position. Could you please help me to understand what is the problem. Is there any relation between the screen coordinates and image coordinates.

    Thanks in advance.

    ReplyDelete