Showing posts with label ColorFilter. Show all posts
Showing posts with label ColorFilter. Show all posts

Tuesday, November 17, 2015

Convert bitmap to grayscale using matrix and ColorMatrixColorFilter


This example show how to convert bitmap to grayscale using matrix and ColorMatrixColorFilter. Once photo loaded, touch on the ImageView will show the original photo, touch release to show the grayscale photo.


MainActivity.java
package com.blogspot.android_er.androidimage;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {

    private static final int RQS_OPEN = 1;
    Button buttonOpen;
    ImageView imageView;

    Bitmap bmNormal, bmGrayScale;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonOpen = (Button) findViewById(R.id.opendocument);
        buttonOpen.setOnClickListener(buttonOpenOnClickListener);

        imageView = (ImageView)findViewById(R.id.image);
        imageView.setOnTouchListener(imageViewOnTouchListener);
    }

    View.OnTouchListener imageViewOnTouchListener = new View.OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if(event.getAction() == MotionEvent.ACTION_DOWN){
                //user touch on ImageView
                if(bmNormal != null){
                    imageView.setImageBitmap(bmNormal);
                }
            }else if(event.getAction() == MotionEvent.ACTION_UP){
                //user release touch on ImageView
                if(bmGrayScale != null){
                    imageView.setImageBitmap(bmGrayScale);
                }
            }
            return true;
        }
    };

    View.OnClickListener buttonOpenOnClickListener =
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("image/*");
                    startActivityForResult(intent, RQS_OPEN);
                }
            };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK && requestCode == RQS_OPEN) {
            Uri dataUri = data.getData();
            int w = imageView.getWidth();
            int h = imageView.getHeight();
            Toast.makeText(MainActivity.this,
                    dataUri.toString() + "\n" +
                    w + " : " + h,
                    Toast.LENGTH_LONG).show();

            try {
                bmNormal = bmGrayScale = null;
                bmNormal = loadScaledBitmap(dataUri, w, h);
                bmGrayScale = getGrayscale(bmNormal);
                imageView.setImageBitmap(bmGrayScale);
                Toast.makeText(MainActivity.this,
                        bmGrayScale.getWidth() + " x " + bmGrayScale.getHeight(),
                        Toast.LENGTH_SHORT).show();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    }

    private Bitmap getGrayscale(Bitmap src){

        //Custom color matrix to convert to GrayScale
        float[] matrix = new float[]{
                0.3f, 0.59f, 0.11f, 0, 0,
                0.3f, 0.59f, 0.11f, 0, 0,
                0.3f, 0.59f, 0.11f, 0, 0,
                0, 0, 0, 1, 0,};

        Bitmap dest = Bitmap.createBitmap(
                src.getWidth(),
                src.getHeight(),
                src.getConfig());

        Canvas canvas = new Canvas(dest);
        Paint paint = new Paint();
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
        paint.setColorFilter(filter);
        canvas.drawBitmap(src, 0, 0, paint);

        return dest;
    }

    /*
    reference:
    Load scaled bitmap
    http://android-er.blogspot.com/2013/08/load-scaled-bitmap.html
     */
    private Bitmap loadScaledBitmap(Uri src, int req_w, int req_h) throws FileNotFoundException {

        Bitmap bm = null;

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(getBaseContext().getContentResolver().openInputStream(src),
                null, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, req_w, req_h);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        bm = BitmapFactory.decodeStream(
                getBaseContext().getContentResolver().openInputStream(src), null, options);

        return bm;
    }

    public int calculateInSampleSize(BitmapFactory.Options options,
                                     int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will
            // guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp"
    android:background="@android:color/black"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/opendocument"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Open Document of Image/Video" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

Wednesday, October 28, 2015

Convert ImageView to black and white, and set brightness, using ColorFilter



MainActivity.java
package com.blogspot.android_er.androidcolorfilter;

import android.graphics.ColorFilter;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.PorterDuff;
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 brightnessBar;
    TextView brightnessInfo;

    PorterDuff.Mode[] optMode = PorterDuff.Mode.values();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView)findViewById(R.id.iv);
        brightnessBar = (SeekBar)findViewById(R.id.bar_brightness);
        brightnessInfo = (TextView)findViewById(R.id.brightness_info);

        brightnessBar.setOnSeekBarChangeListener(brightnessBarChangeListener);

        setBlackAndWhite(imageView);
    }

    SeekBar.OnSeekBarChangeListener brightnessBarChangeListener
            = new SeekBar.OnSeekBarChangeListener(){

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            setBlackAndWhite(imageView);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    };

    private void setBlackAndWhite(ImageView iv){

        float brightness = (float)(brightnessBar.getProgress() - 255);

        float[] colorMatrix = {
                0.33f, 0.33f, 0.33f, 0, brightness, //red
                0.33f, 0.33f, 0.33f, 0, brightness, //green
                0.33f, 0.33f, 0.33f, 0, brightness, //blue
                0, 0, 0, 1, 0    //alpha
        };

        ColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
        iv.setColorFilter(colorFilter);

        brightnessInfo.setText(String.valueOf(brightness));
    }

}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Brightness"/>

    <SeekBar
        android:id="@+id/bar_brightness"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="512"
        android:progress="255"/>

    <TextView
        android:id="@+id/brightness_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Brightness"/>
</LinearLayout>


Related:
- Android example code using ColorFilter

Android example code using ColorFilter



MainActivity.java
package com.blogspot.android_er.androidcolorfilter;

import android.graphics.ColorFilter;
import android.graphics.ColorMatrixColorFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.SeekBar;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    SeekBar redBar, greenBar, blueBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView)findViewById(R.id.iv);
        redBar = (SeekBar)findViewById(R.id.redbar);
        greenBar = (SeekBar)findViewById(R.id.greenbar);
        blueBar = (SeekBar)findViewById(R.id.bluebar);

        redBar.setOnSeekBarChangeListener(colorBarChangeListener);
        greenBar.setOnSeekBarChangeListener(colorBarChangeListener);
        blueBar.setOnSeekBarChangeListener(colorBarChangeListener);

        setColorFilter(imageView);
    }

    SeekBar.OnSeekBarChangeListener colorBarChangeListener
            = new SeekBar.OnSeekBarChangeListener(){

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            setColorFilter(imageView);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    };

    private void setColorFilter(ImageView iv){

       /*
        * 5x4 matrix for transforming the color+alpha components of a Bitmap.
        * The matrix is stored in a single array, and its treated as follows:
        * [  a, b, c, d, e,
        *   f, g, h, i, j,
        *   k, l, m, n, o,
        *   p, q, r, s, t ]
        *
        * When applied to a color [r, g, b, a], the resulting color is computed
        * as (after clamping)
        * R' = a*R + b*G + c*B + d*A + e;
        * G' = f*R + g*G + h*B + i*A + j;
        * B' = k*R + l*G + m*B + n*A + o;
        * A' = p*R + q*G + r*B + s*A + t;
        */

        float redValue = ((float)redBar.getProgress())/255;
        float greenValue = ((float)greenBar.getProgress())/255;
        float blueValue = ((float)blueBar.getProgress())/255;

        float[] colorMatrix = {
                redValue, 0, 0, 0, 0,  //red
                0, greenValue, 0, 0, 0, //green
                0, 0, blueValue, 0, 0,  //blue
                0, 0, 0, 1, 0    //alpha
        };

        ColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
        iv.setColorFilter(colorFilter);
    }

}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>

    <SeekBar
        android:id="@+id/redbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="255"/>
    <SeekBar
        android:id="@+id/greenbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="255"/>
    <SeekBar
        android:id="@+id/bluebar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="255"/>
</LinearLayout>


Related:
- Convert ImageView to black and white, and set brightness, using ColorFilter