How to programmatically change contrast of a bitmap in android?

I want to programmatically change the contrast of bitmap. Till now I have tried this.

private Bitmap adjustedContrast(Bitmap src, double value)
    {
        // image size
        int width = src.getWidth();
        int height = src.getHeight();
        // create output bitmap
        Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
        // color information
        int A, R, G, B;
        int pixel;
        // get contrast value
        double contrast = Math.pow((100 + value) / 100, 2);

        // scan through all pixels
        for(int x = 0; x < width; ++x) {
            for(int y = 0; y < height; ++y) {
                // get pixel color
                pixel = src.getPixel(x, y);
                A = Color.alpha(pixel);
                // apply filter contrast for every channel R, G, B
                R = Color.red(pixel);
                R = (int)(((((R / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
                if(R < 0) { R = 0; }
                else if(R > 255) { R = 255; }

                G = Color.green(pixel);
                G = (int)(((((G / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
                if(G < 0) { G = 0; }
                else if(G > 255) { G = 255; }

                B = Color.blue(pixel);
                B = (int)(((((B / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
                if(B < 0) { B = 0; }
                else if(B > 255) { B = 255; }

                // set new pixel color to output bitmap
                bmOut.setPixel(x, y, Color.argb(A, R, G, B));
            }
        }
        return bmOut;
    }

But this does not work as expected. Please help me in this or provide any other solution to achieve this. Thanks in advance.

  • The container 'Android Dependencies' references non existing library 'facebook-android-sdk\facebook\bin\com_facebook_android.jar'
  • How to calculate dp from pixels in android programmatically
  • Android - notification manager, having a notification without an intent
  • How to NOT close keyboard when DONE on keyboard is pressed
  • Are there any built-in/default sounds that can be utilized in an App?
  • How to make a custom Camera with live Stickers
  • Lazy Loading not working properly
  • Android: anyone know the filename for the “settings” icon?
  • Android- how can I convert android.net.Uri object to java.net.URI object?
  • Scale up Item in RecyclerView to overlaps 2 adjacent items Android
  • Whats the difference between Thread.setPriority() and android.os.Process.setThreadPriority()
  • Firebase Auth not working - 'Update Google Play services' msg on the emulator (Android)
  • 7 Solutions collect form web for “How to programmatically change contrast of a bitmap in android?”

    Try this. Your code didn’t work because you create only a mutable bitmap and didn’t copy the image of source bitmap to the mutable one if i’m not mistaken.

    Hope It helps 🙂

    private Bitmap adjustedContrast(Bitmap src, double value)
    {
        // image size
        int width = src.getWidth();
        int height = src.getHeight();
        // create output bitmap
    
        // create a mutable empty bitmap
        Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
    
        // create a canvas so that we can draw the bmOut Bitmap from source bitmap
        Canvas c = new Canvas();
        c.setBitmap(bmOut);
    
        // draw bitmap to bmOut from src bitmap so we can modify it
        c.drawBitmap(src, 0, 0, new Paint(Color.BLACK));
    
    
        // color information
        int A, R, G, B;
        int pixel;
        // get contrast value
        double contrast = Math.pow((100 + value) / 100, 2);
    
        // scan through all pixels
        for(int x = 0; x < width; ++x) {
            for(int y = 0; y < height; ++y) {
                // get pixel color
                pixel = src.getPixel(x, y);
                A = Color.alpha(pixel);
                // apply filter contrast for every channel R, G, B
                R = Color.red(pixel);
                R = (int)(((((R / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
                if(R < 0) { R = 0; }
                else if(R > 255) { R = 255; }
    
                G = Color.green(pixel);
                G = (int)(((((G / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
                if(G < 0) { G = 0; }
                else if(G > 255) { G = 255; }
    
                B = Color.blue(pixel);
                B = (int)(((((B / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
                if(B < 0) { B = 0; }
                else if(B > 255) { B = 255; }
    
                // set new pixel color to output bitmap
                bmOut.setPixel(x, y, Color.argb(A, R, G, B));
            }
        }
        return bmOut;
    }
    

    Here is complete method:

    /**
     * 
     * @param bmp input bitmap
     * @param contrast 0..10 1 is default
     * @param brightness -255..255 0 is default
     * @return new bitmap
     */
    public static Bitmap changeBitmapContrastBrightness(Bitmap bmp, float contrast, float brightness)
    {
        ColorMatrix cm = new ColorMatrix(new float[]
                {
                    contrast, 0, 0, 0, brightness,
                    0, contrast, 0, 0, brightness,
                    0, 0, contrast, 0, brightness,
                    0, 0, 0, 1, 0
                });
    
        Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
    
        Canvas canvas = new Canvas(ret);
    
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(cm));
        canvas.drawBitmap(bmp, 0, 0, paint);
    
        return ret;
    }
    

    Here is a Renderscript implementation (from the Gradle Example Projects)

    ip.rsh

    #pragma version(1)
    #pragma rs java_package_name(your.app.package)
    

    contrast.rs

    #include "ip.rsh"
    
    static float brightM = 0.f;
    static float brightC = 0.f;
    
    void setBright(float v) {
        brightM = pow(2.f, v / 100.f);
        brightC = 127.f - brightM * 127.f;
    }
    
    void contrast(const uchar4 *in, uchar4 *out)
    {
    #if 0
        out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255);
        out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255);
        out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255);
    #else
        float3 v = convert_float3(in->rgb) * brightM + brightC;
        out->rgb = convert_uchar3(clamp(v, 0.f, 255.f));
    #endif
    }
    

    Java

    private Bitmap changeBrightness(Bitmap original RenderScript rs) {
        Allocation input = Allocation.createFromBitmap(rs, original);
        final Allocation output = Allocation.createTyped(rs, input.getType());
        ScriptC_contrast mScript = new ScriptC_contrast(rs);
        mScript.invoke_setBright(50.f);
        mScript.forEach_contrast(input, output);
        output.copyTo(original);
        return original;
    }
    

    We can use seek bar to adjust contrast.

    enter image description here

    MainActivity.java:

    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.ColorMatrix;
    import android.graphics.ColorMatrixColorFilter;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.ImageView;
    import android.widget.SeekBar;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
        ImageView imageView;
        SeekBar seekbar;
        TextView textView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView = (ImageView) findViewById(R.id.image);
            textView = (TextView) findViewById(R.id.label);
    
            seekbar = (SeekBar) findViewById(R.id.seekbar);
            seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                    imageView.setImageBitmap(changeBitmapContrastBrightness(BitmapFactory.decodeResource(getResources(), R.drawable.lhota), (float) progress / 100f, 1));
                    textView.setText("Contrast: "+(float) progress / 100f);
                }
    
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {}
    
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {}
            });
    
            seekbar.setMax(200);
            seekbar.setProgress(100);
        }
    
        public static Bitmap changeBitmapContrastBrightness(Bitmap bmp, float contrast, float brightness) {
            ColorMatrix cm = new ColorMatrix(new float[]
                    {
                            contrast, 0, 0, 0, brightness,
                            0, contrast, 0, 0, brightness,
                            0, 0, contrast, 0, brightness,
                            0, 0, 0, 1, 0
                    });
    
            Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
    
            Canvas canvas = new Canvas(ret);
    
            Paint paint = new Paint();
            paint.setColorFilter(new ColorMatrixColorFilter(cm));
            canvas.drawBitmap(bmp, 0, 0, paint);
    
            return ret;
        }
    }
    

    activity_main.java:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/label"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:textAppearance="@android:style/TextAppearance.Holo.Medium" />
    
        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    

    http://android.okhelp.cz/bitmap-set-contrast-and-brightness-android/

    have a look at this ,this might solve your problem

    I just had the same problem and ended up using the Color Matrix that Ruslan Yanchyshyn describes. I needed to automatically adjust brightness depending on the image, so I used BoofCV to create a histogram from a scaled version of the image – It took way to long to process the whole image. Then I analyzed the histogram – looked at what was the darkest and brightest colors and then created a color matrix which transforms the colors so the darkest colors are 0 and the brightest colors are 255. In this way the new image uses the whole spectrum from dark/black to light/white now.

    Ended up writing a small post on how I did it on our company blog here if anyone are interested. http://appdictive.dk/blog/projects/2016/07/26/levels_with_color_matrix/

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.