How to get the predominant color in an image?

Asked

Viewed 1,544 times

6

I’m taking a picture of a camera and passing it to a ImagemView and would like to take the predominant color of this image, how could do this on Android?


my next classLaiout ( wrote laiout with i for wanting kk )

package com.example.edras.comeconovo;

import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.graphics.Palette;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import  android.support.v7.graphics.Palette;

public class ProximoLaiout extends ActionBarActivity {


    Button btn1;
    int CAMERA_PIC_REQUEST = 0;
    ImageView imgView;
    int colorpublic;
    public Palette.PaletteAsyncListener mListener;

    public Bitmap mBitmap;


    @Override
    // abrindo a camera e armazenando a foto
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proximo_laiout);
        imgView = (ImageView) findViewById(R.id.img_view);
        btn1 = (Button) findViewById(R.id.btnCores);
        btn1.setCompoundDrawables(null, getResources().getDrawable(R.drawable.olho), null, null);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent camera_intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(camera_intent, CAMERA_PIC_REQUEST);
            }
        });
    }

    @Override
    // exibir a foto no imageview
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 0:
                if (resultCode == RESULT_OK) {
                    Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
                    imgView.setImageBitmap(thumbnail);

                    mListener = new PaletteListener();
                    Palette.generateAsync(thumbnail, mListener);

                }
        }
    }




    public  void clickParaIrConfiguracoes(View view) {
        Intent it = new Intent(this, Configuracoes.class);
        startActivity(it);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_proximo_laiout, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

and in the case of Palettelistener

package com.example.edras.comeconovo;
import android.support.v7.graphics.Palette;


public class PaletteListener implements Palette.PaletteAsyncListener{

    @Override
    public void onGenerated(Palette palette){
        // Pega duas cores predominantes, uma vibrante e uma "muda"(cor com tom cinza) e
        //separa elas em três categorias: normal, leve e escuro.
        int vibrant = palette.getVibrantColor(0x000000);
        int vibrantLight = palette.getLightVibrantColor(0x000000);
        int vibrantDark = palette.getDarkVibrantColor(0x000000);
        int muted = palette.getMutedColor(0x000000);
        int mutedLight = palette.getLightMutedColor(0x000000);
        int mutedDark = palette.getDarkMutedColor(0x000000);

    }
}
  • 2

    A recommendation would be to use the library Palette, Google. With it you can get this information easily.

  • I will not provide an answer because I have no way to test it (I am without the development environment for Android installed). But the principle is simple: build a histogram (more precisely, a color histogram), and select the color that appears most often (i.e., with the largest "bin").

  • You do not need to do an instogram for each separate RGB. You can directly count the occurrence number of each combined value (R+G+B). If I’m not mistaken, the method Bitmap::getPixel is the one used to access pixel values. That question from Soen may also be of some help.

  • you have some example of Palette ? I can’t find any working to use as a base ...

  • This stackoverflow post can help you believe i
 
 http://stackoverflow.com/questions/8471236/finding-the-dominant-color-of-an-image-in-an-android-drawable

1 answer

7


You can use the library Palette Android, because it allows you to extract the color of the image in a simple way ( without having to use histograms, etc.). This library allows the generation of predominant color palettes on an image asynchronously( outside the Uithread) and synchronously( inside the Uithread). In this example I will explain how to make the film generation asynchronously, which is more appropriate. Therefore, we will need to do the following:

  1. Generate color palette asynchronously
  2. Create a class that is Listener, that is, it will receive the color palette as soon as it is generated.

Well, if you’re in Android Studio, to use the library in your project, add the following line inside dependencies in his build.gradle(app).

compile 'com.android.support:palette-v7:21.0.0'

Now let’s get to the steps.

  1. In some class, use the following code to generate a predominant color palette from an image.

    // Gera, de maneira assíncrona, uma paleta de cores baseadas 
    // na sua imagem 'myBitmap' e envia o resultado para um listener 'myListener'.
    Palette palette = Palette.generateAsync(myBitmap,myListener);
    
  2. Create a Listener class that implements the method public void onGenerated(Palette palette) of the interface Palette.PaletteAsyncListener. This method is called as soon as the Listener receives the generated palette.

      @Override
      public void onGenerated(Palette palette) {
          // Acesse o palette gerado e faça o tratamento aqui.
      }
    

A practical example would be:

  1. Minhaacitivity class

     public class MinhaActivity extends AppCompatActivity{
    
        private Palette.PaletteAsyncListener mListener;
        private Bitmap mBitmap;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.meuLayout);
    
            mBitmap = // Realiza os métodos para acessar a foto
    
            mListener = new PaletteListener();
            Palette.generateAsync(mBitmap,mListener);
        }
    }
    
  2. Class Palettelistener

    public class PaletteListener implements Palette.PaletteAsyncListener{
    
        @Override
        public void onGenerated(Palette palette){
    
            // Pega duas cores predominantes, uma vibrante e uma "muda"(cor com tom cinza) e 
           //separa elas em três categorias: normal, leve e escuro.
           int vibrant = palette.getVibrantColor(0x000000);
           int vibrantLight = palette.getLightVibrantColor(0x000000);
           int vibrantDark = palette.getDarkVibrantColor(0x000000);
           int muted = palette.getMutedColor(0x000000);
           int mutedLight = palette.getLightMutedColor(0x000000);
           int mutedDark = palette.getDarkMutedColor(0x000000);
        }
    }
    
  • he accuses that myListener does not exist

  • It is because the myListener must be a class that implements a Palette.PaletteAsyncListener() (ex.: public class MinhaClasse implements Palette.PaletteAsyncListener ) or an object of the type Palette.PaletteAsyncListener, as shown in step two of the answer. In this case, the created class or object would be passed as parameter in the method Palette.generateAsync() of step 1.

  • +1 for the excellent answer. :)

  • Pretty cool the explanation, unfortunately I didn’t have time to do :D would only recommend using the newer version: 22.2.1, which say it’s up to 6x faster. + 1

  • excuse my lack of knowledge more, this giving error my code this so Bitmap thumbnail = (Bitmap) data.getExtras(). get("data");
 imgView.setImageBitmap(thumbnail);
 mListener = new PaletteListener();
 mPalette = Palette.generateAsync(thumbnail, mListener);

esta acusando tipo imcompativel

  • 1

    Sorry, I think I made an error in the answer, I ended up mixing the asynchronous code with synchronous. Do the following: in step 1, remove private Palette mPalette and remove the mPalette = and let Palette.generateAsync(mBitmap,mListener); . Take a test and see if it works. If this is the mistake, let me know before you vote on the answer so I can correct it.

  • the code ran without any error. but as I would return the predominant color to a label?

  • You mean a label of an XML layout ( ex.: <Linearlayout></Linearlayout> ) or an object of the type View ( ex.: Text View, Edit Text, etc. )?

  • actually this work would be for color recognition I take the photo step her to an imageview and speak the predominant color of the image : at first I would like to pass the predominant color to a label in my activity_menu.xml so that the screen reader speaks-if the predominant color. in case I would move to a textview

  • To show the color name things get more boring, because you would have to create a set of pairs key (color name) , value (RGB or HEX value) and for each color, search the name accordingly. But if you want to show only the color value, you can add the following constructor to Palettelistener : public PaletteListener(TextView textView). So when you give new in the Palettelistener, pass the Textview you want as parameter, and then access this Textview in the method onGenerated.

  • ready put the code down here as answer to the question

  • it worked out the code mto thanks, now I only need to find out how to change the color value for hexa or rgb of preference

Show 8 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.