web-dev-qa-db-fra.com

Comment changer la couleur de l'image bitmap dans Android?

Je développe une application Android dans laquelle je mets une image pour imageview. Maintenant, je souhaite modifier la couleur de l'image bitmap par programmation. Supposons que mon image ait une couleur rouge au départ et que je dois maintenant la changer en orange. Comment puis je faire ça? S'il vous plaît aider.

Voici mon code. J'ai réussi à changer l'opacité mais je ne sais pas comment changer la couleur.

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ImageView iv = (ImageView) findViewById(R.id.img);
        Drawable d = getResources().getDrawable(R.drawable.pic1);
        Bitmap mNewBitmap = ((BitmapDrawable)d).getBitmap();
        Bitmap nNewBitmap = adjustOpacity(mNewBitmap);
        iv.setImageBitmap(nNewBitmap);
    }

    private Bitmap adjustOpacity( Bitmap bitmap ) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        int[] pixels = new int[width * height];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        dest.setPixels(pixels, 0, width, 0, 0, width, height);
        return dest;
    } 
38
user456118

J'ai une sorte de solution.

    Bitmap sourceBitmap = BitmapFactory.decodeFile(imgPath);
    float[] colorTransform = {
            0, 1f, 0, 0, 0, 
            0, 0, 0f, 0, 0,
            0, 0, 0, 0f, 0, 
            0, 0, 0, 1f, 0};

    ColorMatrix colorMatrix = new ColorMatrix();
    colorMatrix.setSaturation(0f); //Remove Colour 
    colorMatrix.set(colorTransform); //Apply the Red

    ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
    Paint paint = new Paint();
    Paint.setColorFilter(colorFilter);   

    Display display = getWindowManager().getDefaultDisplay(); 

    Bitmap resultBitmap = Bitmap.createBitmap(sourceBitmap, 0, (int)(display.getHeight() * 0.15), display.getWidth(), (int)(display.getHeight() * 0.75));            

    image.setImageBitmap(resultBitmap);

    Canvas canvas = new Canvas(resultBitmap);
    canvas.drawBitmap(resultBitmap, 0, 0, Paint);
38
user744881

J'ai essayé la réponse de Josip, mais cela ne fonctionnait pas pour moi, que le paramètre offset soit à 1 ou à 0 - le bitmap dessiné venait d'apparaître dans la couleur d'origine.

Cependant, cela a fonctionné:

// You have to copy the bitmap as any bitmaps loaded as drawables are immutable
Bitmap bm = ImageLoader.getInstance().loadImageSync("drawable://" + drawableId, o)
            .copy(Bitmap.Config.ARGB_8888, true);

Paint paint = new Paint();
ColorFilter filter = new PorterDuffColorFilter(ContextCompat.getColor(this, R.color.COLOR_1_DARK), PorterDuff.Mode.SRC_IN);
Paint.setColorFilter(filter);

Canvas canvas = new Canvas(bm);
canvas.drawBitmap(bm, 0, 0, Paint);

Mise à jour 1

Bien que ce qui précède fonctionne bien et soit utile dans de nombreux cas, si vous voulez simplement changer la couleur principale d’un dessin ImageView, ce que l’opération a fait, vous pouvez simplement utiliser:

imgView.setColorFilter(ContextCompat.getColor(this, R.color.COLOR_1_DARK));

Si vous avez besoin de plus de flexibilité ou si cela ne donne pas l'effet souhaité, il existe une surcharge qui vous permet de changer le mode PorterDuff Mode jusqu'à ce que vous obteniez ce que vous cherchez:

imgView.setColorFilter(ContextCompat.getColor(this, R.color.COLOR_1_DARK), PorterDuff.Mode.SRC_ATOP);

Mise à jour 2

Un autre bon cas d’utilisation que j’ai eu pour cela récemment consiste à personnaliser l’apparence d’une icône de marqueur Google map v2. Afin d’utiliser 2 graphiques pour autoriser (par exemple) des icônes de petite/grande taille sur un marqueur, mais également une gamme de couleurs sur ces 2 graphiques en modifiant leur couleur de manière dynamique. Dans mon cas, je le faisais dans ClusterRenderer car les marqueurs étaient également regroupés, mais cela peut être utilisé avec un marqueur de carte ordinaire de la même manière:

@Override
protected void onBeforeClusterItemRendered(MyClusterItem item, MarkerOptions markerOptions) {
    try {
        int markerColor = item.getColor();

        Bitmap icon;

        if (item.isFeatured()) {
            // We must copy the bitmap or we get an exception "Immutable bitmap passed to Canvas constructor"
            icon = BitmapFactory.decodeResource(context.getResources(),
                    R.drawable.icon_marker_large).copy(Bitmap.Config.ARGB_8888, true);
        } else {
            // We must copy the bitmap or we get an exception "Immutable bitmap passed to Canvas constructor"
            icon = BitmapFactory.decodeResource(context.getResources(),
                    R.drawable.icon_marker_small).copy(Bitmap.Config.ARGB_8888, true);
        }

        Paint paint = new Paint();
        ColorFilter filter = new PorterDuffColorFilter(ContextCompat.getColor(context, markerColor), PorterDuff.Mode.SRC_IN);
        Paint.setColorFilter(filter);

        Canvas canvas = new Canvas(icon);
        canvas.drawBitmap(icon, 0, 0, Paint);

        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
50
Breeno
private void changeColor(){
    ImageView image = (ImageView) findViewById(R.id.imageView1);
    Bitmap sourceBitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.ic_launcher);
    changeBitmapColor(sourceBitmap, image, Color.BLUE);

}

private void changeBitmapColor(Bitmap sourceBitmap, ImageView image, int color) {

    Bitmap resultBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0,
            sourceBitmap.getWidth() - 1, sourceBitmap.getHeight() - 1);
    Paint p = new Paint();
    ColorFilter filter = new LightingColorFilter(color, 1);
    p.setColorFilter(filter);
    image.setImageBitmap(resultBitmap);

    Canvas canvas = new Canvas(resultBitmap);
    canvas.drawBitmap(resultBitmap, 0, 0, p);
}
31
Josip

Il vaut mieux obtenir un bitmap modifiable par copie, sans changer de taille:

public static Bitmap changeBitmapColor(Bitmap sourceBitmap, int color)
{
    Bitmap resultBitmap = sourceBitmap.copy(sourceBitmap.getConfig(),true);
    Paint paint = new Paint();
    ColorFilter filter = new LightingColorFilter(color, 1);
    Paint.setColorFilter(filter);
    Canvas canvas = new Canvas(resultBitmap);
    canvas.drawBitmap(resultBitmap, 0, 0, Paint);
    return resultBitmap;
}
8
Aliaksei Rak

Le moyen le plus simple de changer la couleur des bitmaps est d'utiliser cette méthode:

bitmap.eraseColor(ContextCompat.getColor(this, R.color.your_color));

Si vous souhaitez superposer le ImageView avec des couleurs, utilisez:

imageView.setColorFilter(ContextCompat.getColor(this, R.color.your_color));
4
box

Un peu hors sujet, mais considérant que vous voulez seulement afficher en couleur modifiée, voici ma solution. Le moyen le plus simple et rapide consiste simplement à appliquer un filtre par en utilisant la méthode drawColor () sur Canvas, à droite après drawBitmap ()

 m_canvas.drawColor(Color.RED, PorterDuff.Mode.ADD);

Sources: https://developer.Android.com/reference/Android/graphics/PorterDuff.Mode.html

1
TomeeNS

J'ai résolu le problème en utilisant le code ci-dessous  

public void changeColor(Bitmap srcImage) {

    Bitmap bmpRedscale = Bitmap.createBitmap(srcImage.getWidth(), 
    srcImage.getHeight(), Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bmpRedscale);
    Paint paint = new Paint();

    ColorMatrix cm = new ColorMatrix();
    cm.setRGB2YUV();
    Paint.setColorFilter(new ColorMatrixColorFilter(cm));
    canvas.drawBitmap(srcImage, 0, 0, Paint);

    mImgEdited.setImageBitmap(bmpRedscale);
}
0
Akansha patel