get face skin tone color from image - android

i have tried below code that is returning me color of specific pixel which i have pass in argument
int x = (int)event.getX();
int y = (int)event.getY();
int pixel = bitmap.getPixel(x,y);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
int[] color={redValue ,blueValue ,greenValue };
btn.setBackgroundColor(getHexColor(color));
public static int getHexColor(int[] color) {
return android.graphics.Color.rgb(color[0], color[1], color[2]);
}
i have also try color palette following link is reference link that is also not returning perfect skin tone color of face
this is i have also tried
anyone have idea how to extract or get face skin tone color ??

Use this code for getting colors from images.
You can follow this tutorial for further information.
https://medium.com/david-developer/extracting-colors-from-images-integrating-picasso-and-palette-b9ba45c9c418
Palette.from(bitmap)
.generate(new Palette.PaletteAsyncListener() {
#Override
public void onGenerated(Palette palette) {
Palette.Swatch textSwatch = palette.getVibrantSwatch();
if (textSwatch == null) {
Toast.makeText(MainActivity.this, "Null swatch :(", Toast.LENGTH_SHORT).show();
return;
}
backgroundGroup.setBackgroundColor(textSwatch.getRgb());
titleColorText.setTextColor(textSwatch.getTitleTextColor());
bodyColorText.setTextColor(textSwatch.getBodyTextColor());
}
});

Use this
Matrix inverse = new Matrix();
v.getMatrix().invert(inverse);
float[] touchPoint = new float[] {event.getX(), event.getY()};
inverse.mapPoints(touchPoint);
int xCoord = (int) touchPoint[0];
int yCoord = (int) touchPoint[1];
int intColor = ((BitmapDrawable)imageView.getDrawable()).getBitmap().getPixel(xCoord,yCoord);
btn.setBackgroundColor(intColor);
Hope This will help
OR
Simply Change this in you code, don't convert the color pixel to hex.
Use the color pixel directly in setBackGroundColor(pixel)
like
btn.setBackgroundColor(pixel);
This is the full code i have tried
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==(MotionEvent.ACTION_DOWN)){
Matrix inverse = new Matrix();
v.getMatrix().invert(inverse);
float[] touchPoint = new float[] {event.getX(), event.getY()};
inverse.mapPoints(touchPoint);
int xCoord = (int) touchPoint[0];
int yCoord = (int) touchPoint[1];
int intColor = ((BitmapDrawable)imageView.getDrawable()).getBitmap().getPixel(xCoord ,yCoord );
try {
btn.setBackgroundColor(intColor);
}catch (Exception e){
e.printStackTrace();
}
return false;
}
return false;
}
});
Try catch is not necessary but i am putting it only for precaution for any unplanned error

Related

Enable and Disable Zoom in ImageView

I'm using https://github.com/chrisbanes/PhotoView to enable pinch to zoom feature on my custom imageview, however, I'm having a problem with implementing the feature on a toggle button. I wanted to make the image zoom-able when the user clicked the toggle button On. After zooming, when the user clicked the zoom button off, the image should still on its zoomed position but will not be zoomable (because I have another onTouchListener where the user may click and detect colors of the image). Problem is, when the toggle button changes state (on to off), the zoom will reset. Please help me and I'm sorry for my terrible explanation. Thank you.
Below is part of my code:
case R.id.btnZoom:
PhotoViewAttacher photoView= new PhotoViewAttacher(ivImageEditor);
photoView.update();
if(btnZoom.isChecked()){
//photoView.setZoomable(true);
}else if (!btnZoom.isChecked()){
photoView.setZoomable(false);
}
break;
Updated: Below is my activity on which I put the onTouch event for the ImageView to get the pixel colors. (whereas the PhotoView library also override onTouch to enable image zooming). I tried to implement the method from this issue: Android PhotoView Keep Zoom After Orientation Change to keep the scale size/ the zoom size on different state of toggle button but I fail to understand what mScreenBase is. I hope you're able to understand what my problem is. Thanks.
ImageEditorActivity.java:
package com.example.satellite.coloridentifier;
public class ImageEditorActivity extends AppCompatActivity implements View.OnClickListener, TextToSpeech.OnInitListener {
public ImageView ivImageEditor, ivColorPicked;
public TextView tvColorName, tvHexCode, tvRGB;
public ToggleButton btnZoom;
public Bitmap myBitmap;
private float ZoomLevel;
private Matrix theMatrix;
// private RectF rectF;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_editor);
btnZoom = (ToggleButton) findViewById(R.id.btnZoom);
btnZoom.setOnClickListener(this);
ivImageEditor = (ImageView) findViewById(R.id.ivImageEditor);
ivColorPicked = (ImageView) findViewById(R.id.ivColorPicked);
tvColorName = (TextView) findViewById(R.id.tvColorName);
tvHexCode = (TextView) findViewById(R.id.tvHexCode);
tvRGB = (TextView) findViewById(R.id.tvRGB);
// get image or get photo if exist
try {
String imagePath = getIntent().getExtras().getString("imagepath");
String photo = getIntent().getExtras().getString("photoUri");
if (imagePath != null) {
myBitmap = BitmapFactory.decodeFile(imagePath);
ivImageEditor.setImageBitmap(myBitmap);
} else if (photo != null) {
Uri photoUri = Uri.parse(photo);
myBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), photoUri);
ivImageEditor.setImageBitmap(myBitmap);
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "No image or photo", Toast.LENGTH_SHORT).show();
}
//get pixel colors from image on touched parts
ivImageEditor.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (!(ivImageEditor.getDrawable() == null)) {
int touchX = (int) motionEvent.getX();
int touchY = (int) motionEvent.getY();
ivImageEditor.buildDrawingCache();
Bitmap bitmap = ivImageEditor.getDrawingCache();
if (touchX > 0 && touchY > 0 && touchX < bitmap.getWidth() && touchY < bitmap.getHeight()) {
int pixel = bitmap.getPixel(touchX, touchY);
int red = Color.red(pixel);
int myRed = (int) Math.round(red * 100.0 / 255);
int green = Color.green(pixel);
int myGreen = (int) Math.round(green * 100.0 / 255);
int blue = Color.blue(pixel);
int myBlue = (int) Math.round(blue * 100.0 / 255);
updateColorRGB(red, green, blue);
updateColorPercentage(myRed, myGreen, myBlue);
}
}
return true;
}
});
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnZoom:
final PhotoViewAttacher photoView = new PhotoViewAttacher(ivImageEditor);
if (btnZoom.isChecked()) {
photoView.setOnMatrixChangeListener(new PhotoViewAttacher.OnMatrixChangedListener() {
#Override
public void onMatrixChanged(RectF rectF) {
theMatrix = photoView.getDisplayMatrix();
float[] theFloat = new float[9];
theMatrix.getValues( theFloat );
RectF theRect = photoView.getDisplayRect();
if (theRect != null)
{
if( theRect.left > ( ivImageEditor.getWidth() / 2 ) || ( theRect.left >= 0 ) )
{
theRect.left = 0;
}
else
{
theRect.left = ( theRect.left - ( ivImageEditor.getWidth() / 2 ) ) / mScreenBase;
}
if( theRect.top > ( ivImageEditor.getHeight() / 2 ) || ( theRect.top >= 0 ) )
{
theRect.top = 0;
}
else
{
theRect.top = ( theRect.top - ( ivImageEditor.getHeight() / 2 ) ) / mScreenBase;
}
ZoomLevel = photoView.getScale();
}
}
});
} else if (!btnZoom.isChecked()) {
photoView.setScaleType(ImageView.ScaleType.CENTER_CROP);
photoView.setDisplayMatrix(theMatrix);
photoView.setScale(ZoomLevel);
// Toast.makeText(this, "level"+ZoomLevel, Toast.LENGTH_SHORT).show();
ivImageEditor.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (!(ivImageEditor.getDrawable() == null)) {
int touchX = (int) motionEvent.getX();
int touchY = (int) motionEvent.getY();
ivImageEditor.buildDrawingCache();
Bitmap bitmap = ivImageEditor.getDrawingCache();
if (touchX > 0 && touchY > 0 && touchX < bitmap.getWidth() && touchY < bitmap.getHeight()) {
int pixel = bitmap.getPixel(touchX, touchY);
int red = Color.red(pixel);
int myRed = (int) Math.round(red * 100.0 / 255);
int green = Color.green(pixel);
int myGreen = (int) Math.round(green * 100.0 / 255);
int blue = Color.blue(pixel);
int myBlue = (int) Math.round(blue * 100.0 / 255);
updateColorRGB(red, green, blue);
updateColorPercentage(myRed, myGreen, myBlue);
}
}
return true;
}
});
}
break;
default:
break;
}
}
public void updateColorPercentage(int redColor, int greenColor, int blueColor) {
DbHelper myDbHelper = new DbHelper(ImageEditorActivity.this);
String colorName = myDbHelper.getColorName(redColor, greenColor, blueColor);
tvColorName.setText(colorName);
tvRGB.setText("(" + String.valueOf(redColor) + "%, " + String.valueOf(greenColor) + "%, " + String.valueOf(blueColor) + "% )");
}
public void updateColorRGB(int red, int green, int blue) {
String colorHex = String.format("#%02X%02X%02X", red, green, blue);
tvHexCode.setText(colorHex);
ivColorPicked.setBackgroundColor(Color.parseColor(colorHex));
}
}
getSuppMatrix(); allows you to save your PhotoView current state. Then disable or enable zoom and reload your PhotoView with the previous state.
Try this to disable zoom on your PhotoView :
Matrix theMatrix = new Matrix();
mPhotoView.getSuppMatrix(theMatrix);
mPhotoView.setZoomable(false);
mPhotoView.setDisplayMatrix(theMatrix);
And this to re enable zoom :
Matrix theMatrix = new Matrix();
mPhotoView.getSuppMatrix(theMatrix);
mPhotoView.setZoomable(true);
mPhotoView.setDisplayMatrix(theMatrix);
Here is the code for update() and setZoomable function from the library. As you can see they reset the drawable matrix every time the update() is called and zoomable is false. So there is no inbuilt way you can persist the state of the image by using this library.
public void setZoomable(boolean zoomable) {
mZoomEnabled = zoomable;
update();
}
public void update() {
if (mZoomEnabled) {
// Update the base matrix using the current drawable
updateBaseMatrix(mImageView.getDrawable());
} else {
// Reset the Matrix...
resetMatrix();
}
}
Here is the similar issue on GitHub Repo : Issue 168. The solution would be to store the focus point and the scale of the zoomed Image and after setting this : photoView.setZoomable(false);, reassign the focus point and the zoomed scale. This might help you implementing the solution : Android PhotoView Keep Zoom After Orientation Change.
Hope it helps!

Get Color of bitmap pixel even after zoom [duplicate]

I'm using Intent to call and show an image from Gallery, and now I made it enable to get me the coordinates of the image in a TextView using these:
final TextView textView = (TextView)findViewById(R.id.textView);
final TextView textViewCol = (TextView)findViewById(R.id.textViewColor);
targetImage.setOnTouchListener(new ImageView.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int x=0;
int y=0;
textView.setText("Touch coordinates : " +
String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
if(pixel == Color.RED){
textViewCol.setText("It is RED");
}
/*if(redValue == 255){
if(blueValue == 0)
if(greenValue==0)
textViewCol.setText("It is Red");
}*/
return true; }
});
Now what I need to do is; to get the color (RGB value) of the exact coordinates the user selects and later on assign each to #FF0000, #00FF00 and #0000FF but for now, please help to get the Pixel color based on what I have.
Cheers.
You can get the pixel from the view like this:
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
Now you can get each channel with:
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
The Color functions return the value in each channel. So all you have to do is check if Red is 255 and green and blue are 0, than set the textView text to "it is red". Just pay attention that saying that something is red is not simply that the red channel is the greater than zero. 'Cos 255-Green and 255-Red is yellow, of course.
You can also just compare the pixel to different color.
for example:
if(pixel == Color.MAGENTA){
textView.setText("It is Magenta");
}
Hope it helps.
You can modify this for your requirement. This snippet will help you get the pixel color.
public static int getDominantColor(Bitmap bitmap) {
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
final int color = newBitmap.getPixel(0, 0);
newBitmap.recycle();
return color;
}
This works more accurately for me. The key here is to use the View.getDrawingCache instead of DrawableBitmap.
palleteView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent ev) {
// TODO Auto-generated method stub
ImageView img = (ImageView) v;
final int evX = (int) ev.getX();
final int evY = (int) ev.getY();
img.setDrawingCacheEnabled(true);
Bitmap imgbmp = Bitmap.createBitmap(img.getDrawingCache());
img.setDrawingCacheEnabled(false);
try {
int pxl = imgbmp.getPixel(evX, evY);
pickedColorView.setBackgroundColor(pxl);
}catch (Exception ignore){
}
imgbmp.recycle();
return true;
}
});

get lenghths and angles of detected straight Lines

I am working on an android app. I can detect lines using Canny and Hough transform but I don't know how to get the angles and lengths of the detected lines, can you help please? Here's the code:
public void countStraightLines(View view) {
try{
int iCannyLowerThreshold = 45;
int iCannyUpperThreshold = 75;
Mat rgba = Utils.loadResource(getApplicationContext(), res);
Bitmap bmp = Bitmap.createBitmap(rgba.width(), rgba.height(), Bitmap.Config.ARGB_8888);
Mat gray = new Mat ();
Imgproc.cvtColor(rgba, gray, Imgproc.COLOR_BGRA2GRAY, 4);
Imgproc.Canny(gray, gray, iCannyLowerThreshold, iCannyUpperThreshold);
Utils.matToBitmap(gray, bmp);
imgSource.setImageBitmap(bmp);
} catch (IOException e) {
Log.e(TAG, "ERROR Loading Mat");
e.printStackTrace();
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
Globals.pictSelected=parent.getItemAtPosition(position).toString();
res = getResources().getIdentifier(parent.getItemAtPosition(position).toString(), "drawable", this.getPackageName());
try {
Mat rgba = Utils.loadResource(getApplicationContext(), res);
Bitmap bmp = Bitmap.createBitmap(rgba.width(), rgba.height(), Bitmap.Config.ARGB_8888);
Mat gray = new Mat ();
Imgproc.cvtColor(rgba, gray, Imgproc.COLOR_BGRA2GRAY, 4);
int iCannyLowerThreshold = 45;
int iCannyUpperThreshold = 75;
int iHoughLinesThreshold = 50;
int iHoughLinesMinLineSize = 40;
int iHoughLinesGap = 20;
Imgproc.Canny(gray, gray, iCannyLowerThreshold, iCannyUpperThreshold);
Mat lines = new Mat();
Imgproc.HoughLinesP(gray, lines, 1, Math.PI/180, iHoughLinesThreshold, iHoughLinesMinLineSize, iHoughLinesGap);
int x = 0;
char s = 'N';
for (; x < Math.min(lines.cols(), 100); x++)
{
double[] vec = lines.get(0, x);
if (vec == null)
break;
double x1 = vec[0], y1 = vec[1], x2 = vec[2], y2 = vec[3];
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
Core.line(rgba, start, end, new Scalar(255, 0, 0, 255), 1);
if (x >= 40){s = 'C';}
else {s = 'S';}
}
text.setText("Line Count: " + x + " and The Picture is " + s);
Utils.matToBitmap(rgba, bmp);
imgSource.setImageBitmap(bmp);
} catch (IOException e) {
Log.e(TAG, "ERROR Loading Mat");
e.printStackTrace();
}
}
Thank you!
Well, it looks like you have a start point and an end point- the length is just ((starty-endy)^2+(startx-endx)^2)^(1/2). You can get the angle between them by using the fact that the dot product of two vectors A and B A.B=|A|*|B|*cos(alpha) where alpha is the angle between them. So alpha= arccos((A.B)/(|A|*|B|)).

checking pixel color of drawing area [duplicate]

I'm using Intent to call and show an image from Gallery, and now I made it enable to get me the coordinates of the image in a TextView using these:
final TextView textView = (TextView)findViewById(R.id.textView);
final TextView textViewCol = (TextView)findViewById(R.id.textViewColor);
targetImage.setOnTouchListener(new ImageView.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int x=0;
int y=0;
textView.setText("Touch coordinates : " +
String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
if(pixel == Color.RED){
textViewCol.setText("It is RED");
}
/*if(redValue == 255){
if(blueValue == 0)
if(greenValue==0)
textViewCol.setText("It is Red");
}*/
return true; }
});
Now what I need to do is; to get the color (RGB value) of the exact coordinates the user selects and later on assign each to #FF0000, #00FF00 and #0000FF but for now, please help to get the Pixel color based on what I have.
Cheers.
You can get the pixel from the view like this:
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
Now you can get each channel with:
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
The Color functions return the value in each channel. So all you have to do is check if Red is 255 and green and blue are 0, than set the textView text to "it is red". Just pay attention that saying that something is red is not simply that the red channel is the greater than zero. 'Cos 255-Green and 255-Red is yellow, of course.
You can also just compare the pixel to different color.
for example:
if(pixel == Color.MAGENTA){
textView.setText("It is Magenta");
}
Hope it helps.
You can modify this for your requirement. This snippet will help you get the pixel color.
public static int getDominantColor(Bitmap bitmap) {
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
final int color = newBitmap.getPixel(0, 0);
newBitmap.recycle();
return color;
}
This works more accurately for me. The key here is to use the View.getDrawingCache instead of DrawableBitmap.
palleteView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent ev) {
// TODO Auto-generated method stub
ImageView img = (ImageView) v;
final int evX = (int) ev.getX();
final int evY = (int) ev.getY();
img.setDrawingCacheEnabled(true);
Bitmap imgbmp = Bitmap.createBitmap(img.getDrawingCache());
img.setDrawingCacheEnabled(false);
try {
int pxl = imgbmp.getPixel(evX, evY);
pickedColorView.setBackgroundColor(pxl);
}catch (Exception ignore){
}
imgbmp.recycle();
return true;
}
});

How to Get Pixel Color in Android

I'm using Intent to call and show an image from Gallery, and now I made it enable to get me the coordinates of the image in a TextView using these:
final TextView textView = (TextView)findViewById(R.id.textView);
final TextView textViewCol = (TextView)findViewById(R.id.textViewColor);
targetImage.setOnTouchListener(new ImageView.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int x=0;
int y=0;
textView.setText("Touch coordinates : " +
String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
if(pixel == Color.RED){
textViewCol.setText("It is RED");
}
/*if(redValue == 255){
if(blueValue == 0)
if(greenValue==0)
textViewCol.setText("It is Red");
}*/
return true; }
});
Now what I need to do is; to get the color (RGB value) of the exact coordinates the user selects and later on assign each to #FF0000, #00FF00 and #0000FF but for now, please help to get the Pixel color based on what I have.
Cheers.
You can get the pixel from the view like this:
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
Now you can get each channel with:
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
The Color functions return the value in each channel. So all you have to do is check if Red is 255 and green and blue are 0, than set the textView text to "it is red". Just pay attention that saying that something is red is not simply that the red channel is the greater than zero. 'Cos 255-Green and 255-Red is yellow, of course.
You can also just compare the pixel to different color.
for example:
if(pixel == Color.MAGENTA){
textView.setText("It is Magenta");
}
Hope it helps.
You can modify this for your requirement. This snippet will help you get the pixel color.
public static int getDominantColor(Bitmap bitmap) {
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
final int color = newBitmap.getPixel(0, 0);
newBitmap.recycle();
return color;
}
This works more accurately for me. The key here is to use the View.getDrawingCache instead of DrawableBitmap.
palleteView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent ev) {
// TODO Auto-generated method stub
ImageView img = (ImageView) v;
final int evX = (int) ev.getX();
final int evY = (int) ev.getY();
img.setDrawingCacheEnabled(true);
Bitmap imgbmp = Bitmap.createBitmap(img.getDrawingCache());
img.setDrawingCacheEnabled(false);
try {
int pxl = imgbmp.getPixel(evX, evY);
pickedColorView.setBackgroundColor(pxl);
}catch (Exception ignore){
}
imgbmp.recycle();
return true;
}
});

Categories

Resources