Android Picture color correction. How to change brightness, saturation etc of a single image in android?

3.3k views Asked by At

I am developing an app in which user can change the image brightness, contrast,saturation etc. I am able to do all these separately using below code.

 seekBar_brightness.setMax(512);
        seekBar_brightness.setProgress(255);
        seekBar_brightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {


                progress = progress - 255;

                Log.e("ImageColor_bri global", "" + bitmap_global);

                Bitmap new_bm = changeBrightness(bitmap_global, (float) progress);
                Log.e("ImageColor_bri local", "" + new_bm);
                imageView.setImageBitmap(new_bm);
                bitmap_local = new_bm;

               // imageView.getDrawable().setColorFilter(ColorFilterGenerator.adjustBrightness(progress));//foto is my ImageView
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        seekbar_saturation.setMax(512);
        seekbar_saturation.setProgress(255);
        //seekbar_saturation.setThumbOffset(255);
        seekbar_saturation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                 progress = progress-255;
                // imageView.buildDrawingCache();
                // Bitmap bimap = imageView.getDrawingCache();

                //  imageView.setColorFilter(value);
                Log.e("ImageColor_satu global", "" + bitmap_global);
                Bitmap new_bm = adjustSaturation(bitmap_global, progress);
                Log.e("ImageColor_satu local", "" + new_bm);
                imageView.setImageBitmap(new_bm);
                bitmap_local = new_bm;


               // ColorMatrix matrix = new ColorMatrix();
              //  matrix.setSaturation(progress);
               // ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
               // imageView.getDrawable().setColorFilter(ColorFilterGenerator.adjustSaturation(progress));


            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

public static Bitmap changeBrightness(Bitmap bmp, float brightness) {
        ColorMatrix cm = new ColorMatrix(new float[]
                {
                        1, 0, 0, 0, brightness,
                        0, 1, 0, 0, brightness,
                        0, 0, 1, 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;
    }

  public static Bitmap adjustSaturation(Bitmap bmp, float value) {
        value = cleanValue(value, 100);
        if (value == 0) {
            return bmp;
        }

        float x = 1 + ((value > 0) ? 3 * value / 100 : value / 100);
        float lumR = 0.3086f;
        float lumG = 0.6094f;
        float lumB = 0.0820f;

        float[] mat = new float[]
                {
                        lumR * (1 - x) + x, lumG * (1 - x), lumB * (1 - x), 0, 0,
                        lumR * (1 - x), lumG * (1 - x) + x, lumB * (1 - x), 0, 0,
                        lumR * (1 - x), lumG * (1 - x), lumB * (1 - x) + x, 0, 0,
                        0, 0, 0, 1, 0,
                        0, 0, 0, 0, 1
                };

        ColorMatrix cm = new ColorMatrix(mat);

        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;
    }

Problem is : after increasing or decreasing the brightness of image and increasing or decreasing the saturation value changes the image color completely.

I have to achieve that if i reverse to the initial values of seekbar of brightness and saturation i should get the actual image when it was at first time.

E.g if increase the value of brightness from 0 to 100 then change the value of saturation from 0 to 80. Then i reverse the brightness and saturation value to 0. Then i should get the original image as it was at first time.

But now image color does not revers on reversing its value. Please help. Thanx in advance.

1

There are 1 answers

0
Andrii Omelchenko On

This happens because of maximum and minimum brightness (and also saturation and other parameters) value. E.g. if current brightness is 200 and ins increased by 100, brightness value become 255 (not 300) because 255 is max value. If current brightness (now 255) decreased by 100 it becomes 255 - 100 = 155 and become not equals to initial value (200). To avoid this you should store initial bitmap and didn't change it, but change ColorMatrixColorFilter via postConcat() and apply color filter for initial bitmap every time, but not to modified bitmap.

So, you should create global value for ColorMatrix and change it in your changeBrightness() and adjustSaturation() methods and then always apply it to initial bitmap.