Showing posts with label Android code sample: bitmap and image. Show all posts
Showing posts with label Android code sample: bitmap and image. Show all posts

Thursday, May 26, 2016

Load WebP from Internet and display in ListView


WebP is a modern image format that provides superior lossless and lossy compression for images on the web. Details refer Google Developers - WebP.

WebP is supported starting from Android 4.0+ (reference: Android Developers - Supported Media Formats). This example modify from the post "Async load image from internet to ListView" to load WebP from internet and display in ListView. Once item clicked, use "Simplest way to open browser using CustomTabsIntent.Builder".


To use CustomTabsIntent.Builder in our app, To use CustomTabsIntent.Builder, edit app/build.gradle to add dependencies of compile 'com.android.support:customtabs:23.0.0'.

The WebP images load from the page Google Developers - WebP Image Galleries.

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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;

public class MainActivity extends AppCompatActivity {

    final static String src[] = {
            "https://www.gstatic.com/webp/gallery3/1_webp_ll.webp",
            "https://www.gstatic.com/webp/gallery3/1_webp_a.webp",
            "https://www.gstatic.com/webp/gallery3/2_webp_ll.webp",
            "https://www.gstatic.com/webp/gallery3/2_webp_a.webp",
            "https://www.gstatic.com/webp/gallery3/3_webp_ll.webp",
            "https://www.gstatic.com/webp/gallery3/3_webp_a.webp",
            "https://www.gstatic.com/webp/gallery3/4_webp_ll.webp",
            "https://www.gstatic.com/webp/gallery3/4_webp_a.webp",
            "https://www.gstatic.com/webp/gallery3/5_webp_ll.webp",
            "https://www.gstatic.com/webp/gallery3/5_webp_a.webp" };

    ListView imageList;

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

        imageList = (ListView) findViewById(R.id.imagelist);
        ArrayList<String> srcList = new ArrayList<String>(Arrays.asList(src));
        imageList.setAdapter(new CustomListAdapter(this, srcList));

        imageList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String imageSrc = src[position];
                Toast.makeText(MainActivity.this,
                        imageSrc,
                        Toast.LENGTH_LONG).show();

                Uri imageUri = Uri.parse(imageSrc);
                new CustomTabsIntent.Builder()
                        .build()
                        .launchUrl(MainActivity.this, imageUri);
            }
        });
    }

    // ----------------------------------------------------

    public class CustomListAdapter extends BaseAdapter {
        private ArrayList<String> listData;
        private LayoutInflater layoutInflater;

        public CustomListAdapter(Context context, ArrayList<String> listData) {
            this.listData = listData;
            layoutInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return listData.size();
        }

        @Override
        public Object getItem(int position) {
            return listData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = layoutInflater.inflate(R.layout.row, null);
                holder = new ViewHolder();
                holder.icon = (ImageView)convertView.findViewById(R.id.icon);
                holder.text = (TextView)convertView.findViewById(R.id.text);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.text.setText(
                    String.valueOf(position) + "\n" + src[position]);

            if (holder.icon != null) {
                new BitmapWorkerTask(holder.icon).execute(listData.get(position));
            }
            return convertView;
        }

        class ViewHolder {
            ImageView icon;
            TextView text;
        }
    }

    // ----------------------------------------------------
    // Load bitmap in AsyncTask
    // ref:
    // http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
    class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewReference;
        private String imageUrl;

        public BitmapWorkerTask(ImageView imageView) {
            // Use a WeakReference to ensure the ImageView can be garbage
            // collected
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        // Decode image in background.
        @Override
        protected Bitmap doInBackground(String... params) {
            imageUrl = params[0];
            return LoadImage(imageUrl);
        }

        // Once complete, see if ImageView is still around and set bitmap.
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (imageViewReference != null && bitmap != null) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        }

        private Bitmap LoadImage(String URL) {
            Bitmap bitmap = null;
            InputStream in = null;
            try {
                in = OpenHttpConnection(URL);
                bitmap = BitmapFactory.decodeStream(in);
                in.close();
            } catch (IOException e1) {
            }
            return bitmap;
        }

        private InputStream OpenHttpConnection(String strURL)
                throws IOException {
            InputStream inputStream = null;
            URL url = new URL(strURL);
            URLConnection conn = url.openConnection();

            try {
                HttpURLConnection httpConn = (HttpURLConnection) conn;
                httpConn.setRequestMethod("GET");
                httpConn.connect();

                if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    inputStream = httpConn.getInputStream();
                }
            } catch (Exception ex) {
            }
            return inputStream;
        }
    }
}


layout/row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

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="com.blogspot.android_er.androidimage.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" />

    <ListView
        android:id="@+id/imagelist"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>


uses-permission of "android.permission.INTERNET" is needed in AndroidManifest.xml

download filesDownload the files .

Thursday, December 3, 2015

Open image, free draw something on bitmap, and save bitmap to ExternalStorage

Example to load image with intent of Intent.ACTION_PICK, free draw something on the image, and save the bitmap to storage.


I have a series example of "Something about processing images in Android", but have show how to save the result bitmap to SD Card. This example modify from one of the example "Detect touch and free draw on Bitmap", add the function to save the result bitmap to External Storage, with file name "test.jpg".


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="com.blogspot.android_er.androiddrawbitmap.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/loadimage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Image" />

    <Button
        android:id="@+id/saveimage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save Image" />

    <ImageView
        android:id="@+id/result"
        android:scaleType="centerInside"
        android:adjustViewBounds="true"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/background_dark" />
</LinearLayout>


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

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
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.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    Button btnLoadImage, btnSaveImage;
    ImageView imageResult;

    final int RQS_IMAGE1 = 1;

    Uri source;
    Bitmap bitmapMaster;
    Canvas canvasMaster;

    int prvX, prvY;

    Paint paintDraw;

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

        btnLoadImage = (Button)findViewById(R.id.loadimage);
        btnSaveImage = (Button)findViewById(R.id.saveimage);
        imageResult = (ImageView)findViewById(R.id.result);

        paintDraw = new Paint();
        paintDraw.setStyle(Paint.Style.FILL);
        paintDraw.setColor(Color.WHITE);
        paintDraw.setStrokeWidth(10);

        btnLoadImage.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, RQS_IMAGE1);
            }
        });

        btnSaveImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bitmapMaster != null){
                    saveBitmap(bitmapMaster);
                }
            }
        });

        imageResult.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                int action = event.getAction();
                int x = (int) event.getX();
                int y = (int) event.getY();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        prvX = x;
                        prvY = y;
                        drawOnProjectedBitMap((ImageView) v, bitmapMaster, prvX, prvY, x, y);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        drawOnProjectedBitMap((ImageView) v, bitmapMaster, prvX, prvY, x, y);
                        prvX = x;
                        prvY = y;
                        break;
                    case MotionEvent.ACTION_UP:
                        drawOnProjectedBitMap((ImageView) v, bitmapMaster, prvX, prvY, x, y);
                        break;
                }
    /*
     * Return 'true' to indicate that the event have been consumed.
     * If auto-generated 'false', your code can detect ACTION_DOWN only,
     * cannot detect ACTION_MOVE and ACTION_UP.
     */
                return true;
            }
        });
    }

    /*
    Project position on ImageView to position on Bitmap draw on it
     */

    private void drawOnProjectedBitMap(ImageView iv, Bitmap bm,
                                       float x0, float y0, float x, float y){
        if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
            //outside ImageView
            return;
        }else{

            float ratioWidth = (float)bm.getWidth()/(float)iv.getWidth();
            float ratioHeight = (float)bm.getHeight()/(float)iv.getHeight();

            canvasMaster.drawLine(
                    x0 * ratioWidth,
                    y0 * ratioHeight,
                    x * ratioWidth,
                    y * ratioHeight,
                    paintDraw);
            imageResult.invalidate();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        Bitmap tempBitmap;

        if(resultCode == RESULT_OK){
            switch (requestCode){
                case RQS_IMAGE1:
                    source = data.getData();

                    try {
                        //tempBitmap is Immutable bitmap,
                        //cannot be passed to Canvas constructor
                        tempBitmap = BitmapFactory.decodeStream(
                                getContentResolver().openInputStream(source));

                        Bitmap.Config config;
                        if(tempBitmap.getConfig() != null){
                            config = tempBitmap.getConfig();
                        }else{
                            config = Bitmap.Config.ARGB_8888;
                        }

                        //bitmapMaster is Mutable bitmap
                        bitmapMaster = Bitmap.createBitmap(
                                tempBitmap.getWidth(),
                                tempBitmap.getHeight(),
                                config);

                        canvasMaster = new Canvas(bitmapMaster);
                        canvasMaster.drawBitmap(tempBitmap, 0, 0, null);

                        imageResult.setImageBitmap(bitmapMaster);
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    break;
            }
        }
    }

    private void saveBitmap(Bitmap bm){
        File file = Environment.getExternalStorageDirectory();
        File newFile = new File(file, "test.jpg");

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(newFile);
            bm.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
            Toast.makeText(MainActivity.this,
                    "Save Bitmap: " + fileOutputStream.toString(),
                    Toast.LENGTH_LONG).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this,
                    "Something wrong: " + e.getMessage(),
                    Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this,
                    "Something wrong: " + e.getMessage(),
                    Toast.LENGTH_LONG).show();
        }
    }
}


"android.permission.WRITE_EXTERNAL_STORAGE" is needed in AndroidManifest.xml. Also I add android:largeHeap="true" to require more heap for the app. But if you have a really big image, it still will closed, caused by Out Of Memory!
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blogspot.android_er.androiddrawbitmap">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application
        android:largeHeap="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


download filesDownload the files (Android Studio Format) .

more: Something about processing images in Android

Tuesday, November 17, 2015

Display image in opposite color to Trick your brain


This example inspired by the BBC video "Trick your brain: black and white photo turns to colour! - Colour: The Spectrum of Science".

Load your photo, touch the ImageView to display the image of opposite color, look on the blue dot concentratedly for a moment, then release touch to display the black and white image. MAY BE you will be tricked with a color image. try it:)

APK can be download on bottom of this post.


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.Color;
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.LinearLayout;
import android.widget.Toast;

import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {

    private static final int RQS_OPEN = 1;

    LinearLayout panel;
    Button buttonOpen;
    ImageView imageView;
    BlueDot blueDot;

    Bitmap bmNormal, bmGrayScale, bmOpposite;

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

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

        blueDot = (BlueDot)findViewById(R.id.bluedot);
    }

    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(bmOpposite != null){
                    imageView.setImageBitmap(bmOpposite);
                    blueDot.setVisibility(View.VISIBLE);
                }
            }else if(event.getAction() == MotionEvent.ACTION_UP){
                //user release touch on ImageView
                if(bmGrayScale != null){
                    imageView.setImageBitmap(bmGrayScale);
                    blueDot.setVisibility(View.INVISIBLE);
                }
            }
            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();

            try {
                bmNormal = bmGrayScale = bmOpposite = null;
                bmNormal = loadScaledBitmap(dataUri, w, h);
                bmGrayScale = getGrayscale(bmNormal);
                bmOpposite = getOpposite(bmNormal);
                imageView.setImageBitmap(bmGrayScale);

                //hide ui control and action bar to make more space for the picture
                panel.setVisibility(View.GONE);
                getSupportActionBar().hide();
            } 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;
    }

    private Bitmap getOpposite(Bitmap src){

        int w = src.getWidth();
        int h = src.getHeight();

        Bitmap dest = Bitmap.createBitmap(w, h, src.getConfig());

        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                int pixel = src.getPixel(x, y);
                int oppPixel = Color.argb(
                        Color.alpha(pixel),
                        255-Color.red(pixel),
                        255-Color.green(pixel),
                        255-Color.blue(pixel));
                dest.setPixel(x, y, oppPixel);
            }
        }

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

}


Custom view to display a blue dot on screen, BlueDot.java
package com.blogspot.android_er.androidimage;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class BlueDot extends View {

    Paint paint;

    public BlueDot(Context context) {
        super(context);
        init();
    }

    public BlueDot(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public BlueDot(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE);
        paint.setStrokeWidth(5);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int w = canvas.getWidth();
        int h = canvas.getHeight();
        canvas.drawCircle(w/2, h/2, 25, paint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(
                MeasureSpec.getSize(widthMeasureSpec),
                MeasureSpec.getSize(heightMeasureSpec));
    }
}


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">

    <LinearLayout
        android:id="@+id/panel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

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

        <Button
            android:id="@+id/opendocument"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Open" />

    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <com.blogspot.android_er.androidimage.BlueDot
            android:id="@+id/bluedot"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignTop="@id/image"
            android:layout_alignBottom="@id/image"
            android:layout_alignLeft="@id/image"
            android:layout_alignRight="@id/image"
            android:visibility="invisible"/>
    </RelativeLayout>

</LinearLayout>



download filesDownload APK to try.

Load photo and scale-down to suit ImageView


This example show how to load photo using Intent.ACTION_OPEN_DOCUMENT, and scale-down to suitable size, to display in ImageView.


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

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
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;

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

    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 {
                Bitmap bm = loadScaledBitmap(dataUri, w, h);
                imageView.setImageBitmap(bm);
                Toast.makeText(MainActivity.this,
                        bm.getWidth() + " x " + bm.getHeight(),
                        Toast.LENGTH_SHORT).show();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    }

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


Wednesday, April 22, 2015

Async load image from internet to ListView

Android example to load images in AsyncTask from internet to ListView.


MainActivity.java
package com.example.androidasynclist;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;

import android.support.v7.app.ActionBarActivity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

 final static String src[] = {
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh45-l11b9CxlWURRdH3KtwaQYMf7lvCjGjhbao52Wi5r7qrd0Xfth6xTflusBxKTwJe8172h0klxldaYUJESZzyz5prDEKN2dtHrH4IaD-9OTdx1CSkein7e0FMVFBv4WVw4COAQx5vD4/s1600/_01.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggAIxdysN9SF1x7kU-8qHa3-ut75IlMneUrZj008Rnw1uZoRt8cEc08GNuBOrH1oYvERfoGKANoo1GVVAEQMOcYUt3THG0WJXl0nUyv1pYyot_fLYTfBpOvIU4LgKrRdqKbcjNpDAqZjk/s1600/_02.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicQXPrH8ePv6XTHC-gVrwt5IODdKqiaoZUiJpDZBOeKbKt1zS1deLLOIdpxLYCXCnuXTIP2ZaCFsLY49sDOmda6-S6kHJBaCrbzNlsXornSIPOW3J__TaAYj4mN6kniZIHnKlOD7XSRzE/s1600/_03.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibJPrKh6gadVz_Lk9WB88l2h1eFjXzwzltzT3qawdhx-whIker16zNLjjdOlZK6ZQb-g-Gh8f6KQgKNz3LEM6lV_uTfRjB_Jqyijx0UhXCDiBk2PmGeG9JepX3SKtG9smYIgCxoz6YBcg/s1600/_04.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJYw1j_8u6OyPr-X5kxKghanaf4uZgWykHGnR4T82FJ8X8KeVcZFT91aNR-mcUKYh8_VW4g6bC_VwskODH9yEu4Q3S_0bdtzx7fixquKWv0BVJGILN-b0vpvXGerWTPf-H6xqtmHPAq74/s1600/_05.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisebiSsu0boJ3EncEPMYnLj8MEvb2amGp0W4jrvTz-htJos8CHlUjtqALhC3Z1tS73zY1cKDn14WDJ0qqsIEova5rGxtKqfGw4jaPAWpUpWlM7OWrQrTthmZuXDlvONPUP_ixqypr1R5Y/s1600/_06.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxZwuI5jNXioK2PBfvFkhcyNj-qGTmnB8_pXATaGl5VwKWitoWAbe_OecmK-LimzJ95x_YmYjgrOY2xCLr9ScwzOalPC_1wx1l3rWvN-SKkYinS-LjQoei6OiuCA5Vhqz5XjEwrCfFv4A/s1600/_07.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN_NWFc1tGg7yOlyj_ytqlzlAeUyjL-EOehYIKwpjqIZFdpiFxFK292j5Nl2Nercsb0JVcMGk0BNJ_7DwShmOhzbtAOreQBxXV5Kf-PnxizNC-g-relCv2ojBgAHJHIRG_kE0-B1xVx2I/s1600/_08.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvnZ4Mucl5g31ikF1BFvcPP4L2ligLXcw71xjpTIgpgbw9ycf0kGWC_dE6asoXoQq4BOY-mdKQoe6dCUpTca5jMM2BBTjigDqbvvePkhx4hPkmHvhm7HlgYj5UMGZHmBbSCrleitJ2ekQ/s1600/_09.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM-Pv79aw3p7_5zjgN08vWs6_qx7QHGxVX9kofXoAoShjrURoMNk10AgH5intycrEB6o4nb215IqkeAUGjo7A8aBRFUe_052Vmn5cY7rIYyaxFCVbeJTADl0lYj4kD71t2psHKYAsk3Uw/s1600/_10.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQAPsubpaTgVDk1vkG8Ktml3nljEBbRfva7J3hqQ1QfJZ1wdKp9UIbm8-JNyCeHwmPFEGpZ5GEih6Zgn9giK3Gcfbka8Sbqfj-0VqvCUzu7w3JbZ6QTMwGmf10zil_xeDz0p6zPopN0nY/s1600/_11.png",
   "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidlI97E_km-6-Yx-xqrccSG5TNH5e_RU-NTOesxP1SCQMMf2ft1TQrwIA8MnapXjPrLDuzaJDzD4Eni11C7dqTJAY37LympC128pGE0OyBSZzRhyphenhyphenPYxovNdmI_JgP8l0B5dVcoK_txhy4/s1600/_12.png" };

 ListView imageList;

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

  imageList = (ListView) findViewById(R.id.imagelist);
  ArrayList<String> srcList = new ArrayList<String>(Arrays.asList(src));
  imageList.setAdapter(new CustomListAdapter(this, srcList));
 }

 // ----------------------------------------------------

 public class CustomListAdapter extends BaseAdapter {
  private ArrayList<String> listData;
  private LayoutInflater layoutInflater;

  public CustomListAdapter(Context context, ArrayList<String> listData) {
   this.listData = listData;
   layoutInflater = LayoutInflater.from(context);
  }

  @Override
  public int getCount() {
   return listData.size();
  }

  @Override
  public Object getItem(int position) {
   return listData.get(position);
  }

  @Override
  public long getItemId(int position) {
   return position;
  }

  public View getView(int position, View convertView, ViewGroup parent) {
   ViewHolder holder;
   if (convertView == null) {
    convertView = layoutInflater.inflate(R.layout.row, null);
    holder = new ViewHolder();
    holder.icon = (ImageView)convertView.findViewById(R.id.icon);
    holder.text = (TextView)convertView.findViewById(R.id.text);
    convertView.setTag(holder);
   } else {
    holder = (ViewHolder) convertView.getTag();
   }
   
   holder.text.setText(String.valueOf(position));

   if (holder.icon != null) {
    new BitmapWorkerTask(holder.icon).execute(listData.get(position));
   }
   return convertView;
  }

  class ViewHolder {
   ImageView icon;
   TextView text;
  }
 }

 // ----------------------------------------------------
 // Load bitmap in AsyncTask
 // ref:
 // http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
 class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
  private final WeakReference<ImageView> imageViewReference;
  private String imageUrl;

  public BitmapWorkerTask(ImageView imageView) {
   // Use a WeakReference to ensure the ImageView can be garbage
   // collected
   imageViewReference = new WeakReference<ImageView>(imageView);
  }

  // Decode image in background.
  @Override
  protected Bitmap doInBackground(String... params) {
   imageUrl = params[0];
   return LoadImage(imageUrl);
  }

  // Once complete, see if ImageView is still around and set bitmap.
  @Override
  protected void onPostExecute(Bitmap bitmap) {
   if (imageViewReference != null && bitmap != null) {
    final ImageView imageView = imageViewReference.get();
    if (imageView != null) {
     imageView.setImageBitmap(bitmap);
    }
   }
  }

  private Bitmap LoadImage(String URL) {
   Bitmap bitmap = null;
   InputStream in = null;
   try {
    in = OpenHttpConnection(URL);
    bitmap = BitmapFactory.decodeStream(in);
    in.close();
   } catch (IOException e1) {
   }
   return bitmap;
  }

  private InputStream OpenHttpConnection(String strURL)
    throws IOException {
   InputStream inputStream = null;
   URL url = new URL(strURL);
   URLConnection conn = url.openConnection();

   try {
    HttpURLConnection httpConn = (HttpURLConnection) conn;
    httpConn.setRequestMethod("GET");
    httpConn.connect();

    if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
     inputStream = httpConn.getInputStream();
    }
   } catch (Exception ex) {
   }
   return inputStream;
  }
 }
}

/res/layout/activity_main.xml
<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidasynclist.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" />

    <ListView
        android:id="@+id/imagelist"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

/res/layout/row.xml
<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="wrap_content"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Permission of "android.permission.INTERNET" is needed in AndroidManifest.xml.



download filesDownload the files.

Related:
Load WebP from Internet and display in ListView

Tuesday, April 21, 2015

Save Bitmap to storage

This example show how to save bitmap to storage (SD Card) as file, and insert to MediaStore.


As a example, the bitmap is retrieved from ImageView by calling ((BitmapDrawable)imageView.getDrawable()).getBitmap(), note that it's not always work, depends on how to load image to ImageVIew.

To save file to external storage, permission of "android.permission.WRITE_EXTERNAL_STORAGE" is needed in AndroidManifest.xml. Otherwise you cannot save the file, but no error reported.

In this example:
- The first button save the bitmap as file, with specified path. In this case, MediaStore may not know there are new image, such that may be you cannot view it in Android Gallery App or Photos App.
- The second button insert the bitmap to MediaStore by calling MediaStore.Images.Media.insertImage(ContentResolver cr, Bitmap source, String title, String description), to MediaStore path. Such that you can view it in Android Gallery App or Photos App.
- The third button save the bitmap as file, then insert the file to MediaStore by calling MediaStore.Images.Media.insertImage(ContentResolver cr, String imagePath, String name, String description). In this case, you save two files actually.


package com.example.androidsavebitmap;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.support.v7.app.ActionBarActivity;
import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

/*
 * "android.permission.WRITE_EXTERNAL_STORAGE" is needed
 * otherwise, cannot save but no error report
 */

public class MainActivity extends ActionBarActivity {
 
 ImageView imageView;
 Button btnSaveExternalStorageDirectory;
 Button btnSaveMediaStore;
 Button btnSaveFileAndMediaStore;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView)findViewById(R.id.image);
        
        btnSaveExternalStorageDirectory = (Button)findViewById(R.id.saveExternalStorageDirectory);
        btnSaveExternalStorageDirectory.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    /*
     * Save bitmap to ExternalStorageDirectory
     */
    
    //get bitmap from ImageVIew
    //not always valid, depends on your drawable
    Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

    //always save as 
       String fileName = "test.jpg";
       
       ByteArrayOutputStream bytes = new ByteArrayOutputStream();
       bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);

    File ExternalStorageDirectory = Environment.getExternalStorageDirectory();
    File file = new File(ExternalStorageDirectory + File.separator + fileName);
    
    FileOutputStream fileOutputStream = null;
    try {
     file.createNewFile();
     fileOutputStream = new FileOutputStream(file);
     fileOutputStream.write(bytes.toByteArray());
     
     Toast.makeText(MainActivity.this, 
       file.getAbsolutePath(), 
       Toast.LENGTH_LONG).show();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } finally {
     if(fileOutputStream != null){
      try {
       fileOutputStream.close();
      } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
    }

   }});
        
        btnSaveMediaStore = (Button)findViewById(R.id.saveMediaStore);
        btnSaveMediaStore.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    /*
     * Save bitmap to MediaStore
     */
    
    //get bitmap from ImageVIew
    //not always valid, depends on your drawable
    Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

    ContentResolver cr = getContentResolver();
    String title = "myBitmap";
    String description = "My bitmap created by Android-er";
    String savedURL = MediaStore.Images.Media
      .insertImage(cr, bitmap, title, description);
    
    Toast.makeText(MainActivity.this, 
      savedURL, 
      Toast.LENGTH_LONG).show();
    
   }});
        
        btnSaveFileAndMediaStore = (Button)findViewById(R.id.saveExternalStorageDirectoryMediaStore);
        btnSaveFileAndMediaStore.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    /*
     * Save bitmap to ExternalStorageDirectory
     */
    
    //get bitmap from ImageVIew
    //not always valid, depends on your drawable
    Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

    //always save as 
       String fileName = "test.jpg";
       
       ByteArrayOutputStream bytes = new ByteArrayOutputStream();
       bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);

    File ExternalStorageDirectory = Environment.getExternalStorageDirectory();
    File file = new File(ExternalStorageDirectory + File.separator + fileName);
    
    FileOutputStream fileOutputStream = null;
    try {
     file.createNewFile();
     fileOutputStream = new FileOutputStream(file);
     fileOutputStream.write(bytes.toByteArray());
     
     ContentResolver cr = getContentResolver();
     String imagePath = file.getAbsolutePath();
     String name = file.getName();
     String description = "My bitmap created by Android-er";
     String savedURL = MediaStore.Images.Media
       .insertImage(cr, imagePath, name, description);
     
     Toast.makeText(MainActivity.this, 
       savedURL, 
       Toast.LENGTH_LONG).show();
     
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } finally {
     if(fileOutputStream != null){
      try {
       fileOutputStream.close();
      } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
    }

   }});
    }

}


<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidsavebitmap.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/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <Button
        android:id="@+id/saveExternalStorageDirectory"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save to ExternalStorageDirectory" />

    <Button
        android:id="@+id/saveMediaStore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save to MediaStore" />

    <Button
        android:id="@+id/saveExternalStorageDirectoryMediaStore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save to ExternalStorageDirectory and insert to MediaStore" />

</LinearLayout>


download filesDownload the files.

more:
Insert the bitmap to MediaStore with title and List images title in MediaStore

Monday, March 16, 2015

Draw text on Bitmap

Example to draw text on Bitmap.


package com.example.androidimageview;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.SeekBar;

public class MainActivity extends ActionBarActivity {

 SeekBar textSizeBar;
 ImageView image1, image2;
 Button btnDrawText;
 EditText textIn;

 Bitmap bitmapOriginal;

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

  textSizeBar = (SeekBar) findViewById(R.id.textsize);
  btnDrawText = (Button) findViewById(R.id.drawtext);
  textIn = (EditText) findViewById(R.id.textin);
  image1 = (ImageView) findViewById(R.id.image1);
  image2 = (ImageView) findViewById(R.id.image2);

  bitmapOriginal = BitmapFactory.decodeResource(getResources(),
    R.drawable.ic_launcher);
  image1.setImageBitmap(bitmapOriginal);

  btnDrawText.setOnClickListener(btnDrawTextOnClickListener);

  ReloadImage();

 }
 
 OnClickListener btnDrawTextOnClickListener = new OnClickListener(){

  @Override
  public void onClick(View v) {
   ReloadImage();
  }};

 private void ReloadImage() {

  int textSize = textSizeBar.getProgress();
  String textToDraw = textIn.getText().toString();

  Bitmap newBitmap = bitmapOriginal.copy(bitmapOriginal.getConfig(), true);

  Canvas newCanvas = new Canvas(newBitmap);
  Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  paint.setColor(Color.RED);
  paint.setTextSize(textSize);

  Rect bounds = new Rect();
  paint.getTextBounds(textToDraw, 0, textToDraw.length(), bounds);
  int x = 0;
  int y = newBitmap.getHeight();
  
  newCanvas.drawText(textToDraw, x, y, paint);
  
  image1.setImageBitmap(newBitmap);
  image2.setImageBitmap(newBitmap);

 }

}

<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidimageview.MainActivity" >

    <TextView
        android:id="@+id/title"
        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" />
    
    <EditText
        android:id="@+id/textin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <SeekBar
        android:id="@+id/textsize"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="50"
        android:progress="10" />
    
    <Button
        android:id="@+id/drawtext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Draw text on bitmap" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/image1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        
        <ImageView
            android:id="@+id/image2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#D0D0D0" />
    </LinearLayout>

</LinearLayout>


Tuesday, March 10, 2015

Merge bitmaps

Example show how to combin two bitmaps to one.


package com.example.androidimageview;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends ActionBarActivity {

 SeekBar xScaleBar, yScaleBar;
 ImageView image1, image2, image3, image4;

 Bitmap bitmapOriginal;

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

  xScaleBar = (SeekBar) findViewById(R.id.xscale);
  yScaleBar = (SeekBar) findViewById(R.id.yscale);
  image1 = (ImageView) findViewById(R.id.image1);
  image2 = (ImageView) findViewById(R.id.image2);
  image3 = (ImageView) findViewById(R.id.image3);
  image4 = (ImageView) findViewById(R.id.image4);

  bitmapOriginal = BitmapFactory.decodeResource(getResources(),
    R.drawable.ic_launcher);
  image1.setImageBitmap(bitmapOriginal);

  xScaleBar.setOnSeekBarChangeListener(OnScaleChangeListener);
  yScaleBar.setOnSeekBarChangeListener(OnScaleChangeListener);

  ReloadImage();

 }

 OnSeekBarChangeListener OnScaleChangeListener = new OnSeekBarChangeListener() {

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

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {
  }

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
   ReloadImage();
  }
 };

 private void ReloadImage() {

  float xScale = (float)(xScaleBar.getProgress()-10) / 10.0f;
  float yScale = (float)(yScaleBar.getProgress()-10) / 10.0f;

  //between +1 and -1,
  //cannot be 0
  if (xScale >= 0 && xScale < 0.1f) {
   xScale = 0.1f;
  }else if(xScale < 0 && xScale > -0.1f){
   xScale = -0.1f;
  }

  if (yScale >= 0 && yScale < 0.1f) {
   yScale = 0.1f;
  }else if(yScale < 0 && yScale > -0.1f){
   yScale = -0.1f;
  }

  // create scaled bitmap using Matrix
  Matrix matrix = new Matrix();
  matrix.postScale(xScale, yScale);

  Bitmap bitmapScaled = Bitmap.createBitmap(bitmapOriginal, 0, 0,
    bitmapOriginal.getWidth(), bitmapOriginal.getHeight(), matrix,
    false);

  image2.setImageBitmap(bitmapScaled);
  
  //Merge two bitmaps to one
  Bitmap bitmapMerged = Bitmap.createBitmap(
    bitmapOriginal.getWidth(), 
    bitmapOriginal.getHeight(), 
    bitmapOriginal.getConfig()); 
  Canvas canvasMerged = new Canvas(bitmapMerged);
  canvasMerged.drawBitmap(bitmapOriginal, 0, 0, null);
  canvasMerged.drawBitmap(bitmapScaled, 0, 0, null);
  
  image3.setImageBitmap(bitmapMerged);
  image4.setImageBitmap(bitmapMerged);

 }

}

<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidimageview.MainActivity" >

    <TextView
        android:id="@+id/title"
        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" />

    <SeekBar
        android:id="@+id/xscale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="20"
        android:progress="20" />

    <SeekBar
        android:id="@+id/yscale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="20"
        android:progress="20" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/image1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/image2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#D0D0D0" />

        <ImageView
            android:id="@+id/image3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#B0B0B0" />
        
        <ImageView
            android:id="@+id/image4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#909090" />
    </LinearLayout>

</LinearLayout>


Monday, March 9, 2015

Flip bitmap using Matrix

Example to create flipped bitmap using Matrix.


package com.example.androidimageview;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends ActionBarActivity {

 SeekBar xScaleBar, yScaleBar;
 ImageView image1, image2, image3;

 Bitmap bitmapOriginal;

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

  xScaleBar = (SeekBar) findViewById(R.id.xscale);
  yScaleBar = (SeekBar) findViewById(R.id.yscale);
  image1 = (ImageView) findViewById(R.id.image1);
  image2 = (ImageView) findViewById(R.id.image2);
  image3 = (ImageView) findViewById(R.id.image3);

  bitmapOriginal = BitmapFactory.decodeResource(getResources(),
    R.drawable.ic_launcher);
  image1.setImageBitmap(bitmapOriginal);

  xScaleBar.setOnSeekBarChangeListener(OnScaleChangeListener);
  yScaleBar.setOnSeekBarChangeListener(OnScaleChangeListener);

  ReloadImage();

 }

 OnSeekBarChangeListener OnScaleChangeListener = new OnSeekBarChangeListener() {

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

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {
  }

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
   ReloadImage();
  }
 };

 private void ReloadImage() {

  float xScale = (float)(xScaleBar.getProgress()-10) / 10.0f;
  float yScale = (float)(yScaleBar.getProgress()-10) / 10.0f;

  //between +1 and -1,
  //cannot be 0
  if (xScale >= 0 && xScale < 0.1f) {
   xScale = 0.1f;
  }else if(xScale < 0 && xScale > -0.1f){
   xScale = -0.1f;
  }

  if (yScale >= 0 && yScale < 0.1f) {
   yScale = 0.1f;
  }else if(yScale < 0 && yScale > -0.1f){
   yScale = -0.1f;
  }

  // create scaled bitmap using Matrix
  Matrix matrix = new Matrix();
  matrix.postScale(xScale, yScale);

  Bitmap bitmapScaled = Bitmap.createBitmap(bitmapOriginal, 0, 0,
    bitmapOriginal.getWidth(), bitmapOriginal.getHeight(), matrix,
    false);

  image2.setImageBitmap(bitmapScaled);
  image3.setImageBitmap(bitmapScaled);

 }

}

<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidimageview.MainActivity" >

    <TextView
        android:id="@+id/title"
        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" />

    <SeekBar
        android:id="@+id/xscale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="20"
        android:progress="20" />

    <SeekBar
        android:id="@+id/yscale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="20"
        android:progress="20" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/image1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/image2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#D0D0D0" />

        <ImageView
            android:id="@+id/image3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#B0B0B0" />
    </LinearLayout>

</LinearLayout>


Sunday, March 8, 2015

Rotate bitmap using Matrix

Example show how to create rotated bitmap using Matrix.


package com.example.androidimageview;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends ActionBarActivity {

 SeekBar rotateBar;
 ImageView image1, image2, image3;

 Bitmap bitmapOriginal;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  rotateBar = (SeekBar)findViewById(R.id.rotate);
  image1 = (ImageView) findViewById(R.id.image1);
  image2 = (ImageView) findViewById(R.id.image2);
  image3 = (ImageView) findViewById(R.id.image3);

  bitmapOriginal = BitmapFactory.decodeResource(getResources(),
    R.drawable.ic_launcher);
  image1.setImageBitmap(bitmapOriginal);
  
  rotateBar.setOnSeekBarChangeListener(OnRotateChangeListener);

  ReloadImage();

 }
 
 OnSeekBarChangeListener OnRotateChangeListener = new OnSeekBarChangeListener(){

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

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {}

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
   ReloadImage();
  }};
  
 private void ReloadImage(){
  
  float degrees = rotateBar.getProgress() - 180;

  //create rotated bitmap using Matrix
        Matrix matrix = new Matrix();
        matrix.postRotate(degrees, 
         bitmapOriginal.getWidth()/2, bitmapOriginal.getHeight()/2);
        
        Bitmap bitmapRot = Bitmap.createBitmap(
          bitmapOriginal, 
          0, 0, 
          bitmapOriginal.getWidth(), bitmapOriginal.getHeight(), 
          matrix, true);

  image2.setImageBitmap(bitmapRot);
  image3.setImageBitmap(bitmapRot);
 }

}

<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidimageview.MainActivity" >

    <TextView
        android:id="@+id/title"
        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" />

    <SeekBar
        android:id="@+id/rotate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="360"
        android:progress="180" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/image1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/image2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#D0D0D0" />

        <ImageView
            android:id="@+id/image3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#B0B0B0" />
    </LinearLayout>

</LinearLayout>


Scale bitmap using Matrix

This example show how to create scaled bitmap using Matrix.


package com.example.androidimageview;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends ActionBarActivity {

 SeekBar xScaleBar, yScaleBar;
 ImageView image1, image2;

 Bitmap bitmapOriginal;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  xScaleBar = (SeekBar)findViewById(R.id.xscale);
  yScaleBar = (SeekBar)findViewById(R.id.yscale);
  image1 = (ImageView) findViewById(R.id.image1);
  image2 = (ImageView) findViewById(R.id.image2);

  bitmapOriginal = BitmapFactory.decodeResource(getResources(),
    R.drawable.ic_launcher);
  image1.setImageBitmap(bitmapOriginal);
  
  xScaleBar.setOnSeekBarChangeListener(OnScaleChangeListener);
  yScaleBar.setOnSeekBarChangeListener(OnScaleChangeListener);
  
  Toast.makeText(MainActivity.this, 
    bitmapOriginal.getWidth() + " x " + bitmapOriginal.getHeight(), 
    Toast.LENGTH_LONG).show();
  
  ReloadImage();

 }
 
 OnSeekBarChangeListener OnScaleChangeListener = new OnSeekBarChangeListener(){

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

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {}

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
   ReloadImage();
  }};
  
 private void ReloadImage(){
  
  float xScale = xScaleBar.getProgress()/10.0f;
  float yScale = yScaleBar.getProgress()/10.0f;

  if(xScale<=0){
   xScale = 0.1f;
  }
  
  if(yScale<=0){
   yScale = 0.1f;
  }
  
  //create scaled bitmap using Matrix
  Matrix matrix = new Matrix();
        matrix.postScale(xScale, yScale);

        Bitmap bitmapScaled = Bitmap.createBitmap(
          bitmapOriginal, 
          0, 0, 
          bitmapOriginal.getWidth(), bitmapOriginal.getHeight(), 
          matrix, true);

  image2.setImageBitmap(bitmapScaled);

 }

}

<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidimageview.MainActivity" >

    <TextView
        android:id="@+id/title"
        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" />

    <SeekBar
        android:id="@+id/xscale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="30"
        android:progress="10" />

    <SeekBar
        android:id="@+id/yscale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="30"
        android:progress="10" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/image1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/image2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>


Sunday, March 1, 2015

interactive exercise of ScriptIntrinsicConvolve3x3

Last example show how to "Sharpen and blur bitmap using ScriptIntrinsicConvolve3x3", here is a interactive exercise of ScriptIntrinsicConvolve3x3. You can adjust coefficients of ScriptIntrinsicConvolve3x3, and view the result.


package com.example.androidimageview;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicConvolve3x3;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

 ImageView image1, image2;
 SeekBar coeff0, coeff1, coeff2;
 SeekBar coeff3, coeff4, coeff5;
 SeekBar coeff6, coeff7, coeff8;
 SeekBar devBy;
 Button btnBlur, btnOrg, btnSharpen;
 
 TextView textCoeff;
 
 float[] matrix = {
   0, 0, 0,
   0, 1, 0,
   0, 0, 0
 };

 Bitmap bitmapOriginal, bitmapCoeff;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  coeff0 = (SeekBar)findViewById(R.id.coeff0);
  coeff1 = (SeekBar)findViewById(R.id.coeff1);
  coeff2 = (SeekBar)findViewById(R.id.coeff2);
  coeff3 = (SeekBar)findViewById(R.id.coeff3);
  coeff4 = (SeekBar)findViewById(R.id.coeff4);
  coeff5 = (SeekBar)findViewById(R.id.coeff5);
  coeff6 = (SeekBar)findViewById(R.id.coeff6);
  coeff7 = (SeekBar)findViewById(R.id.coeff7);
  coeff8 = (SeekBar)findViewById(R.id.coeff8);
  devBy = (SeekBar)findViewById(R.id.coeffdivby);
  textCoeff = (TextView)findViewById(R.id.textcoeff);
  btnBlur = (Button)findViewById(R.id.blur);
  btnOrg = (Button)findViewById(R.id.org);
  btnSharpen = (Button)findViewById(R.id.sharpen);
  image1 = (ImageView) findViewById(R.id.image1);
  image2 = (ImageView) findViewById(R.id.image2);

  bitmapOriginal = BitmapFactory.decodeResource(getResources(),
    R.drawable.ic_launcher);
  
  coeff0.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff1.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff2.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff3.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff4.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff5.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff6.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff7.setOnSeekBarChangeListener(OnCoeffChangeListener);
  coeff8.setOnSeekBarChangeListener(OnCoeffChangeListener);
  devBy.setOnSeekBarChangeListener(OnCoeffChangeListener);
  
  ReloadImage();
  
  btnBlur.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    coeff0.setProgress(1+10);
    coeff1.setProgress(1+10);
    coeff2.setProgress(1+10);
    coeff3.setProgress(1+10);
    coeff4.setProgress(1+10);
    coeff5.setProgress(1+10);
    coeff6.setProgress(1+10);
    coeff7.setProgress(1+10);
    coeff8.setProgress(1+10);
    devBy.setProgress(9-1);
    ReloadImage();
   }});
  
  btnOrg.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    coeff0.setProgress(0+10);
    coeff1.setProgress(0+10);
    coeff2.setProgress(0+10);
    coeff3.setProgress(0+10);
    coeff4.setProgress(1+10);
    coeff5.setProgress(0+10);
    coeff6.setProgress(0+10);
    coeff7.setProgress(0+10);
    coeff8.setProgress(0+10);
    devBy.setProgress(1-1);
    ReloadImage();
   }});
  
  btnSharpen.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    coeff0.setProgress(0+10);
    coeff1.setProgress(-1+10);
    coeff2.setProgress(0+10);
    coeff3.setProgress(-1+10);
    coeff4.setProgress(5+10);
    coeff5.setProgress(-1+10);
    coeff6.setProgress(0+10);
    coeff7.setProgress(-1+10);
    coeff8.setProgress(0+10);
    devBy.setProgress(1-1);
    ReloadImage();
   }});
 }
 
 OnSeekBarChangeListener OnCoeffChangeListener = new OnSeekBarChangeListener(){

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

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {}

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
   ReloadImage();
  }};
  
 private void ReloadImage(){
  updateMatrix();
  bitmapCoeff = createBitmap_convolve(bitmapOriginal, matrix);
  image1.setImageBitmap(bitmapCoeff);
  image2.setImageBitmap(bitmapCoeff);
 }
 
 private void updateMatrix(){
  float div = devBy.getProgress() + 1;
  matrix[0] = (coeff0.getProgress()-10)/div;
  matrix[1] = (coeff1.getProgress()-10)/div;
  matrix[2] = (coeff2.getProgress()-10)/div;
  matrix[3] = (coeff3.getProgress()-10)/div;
  matrix[4] = (coeff4.getProgress()-10)/div;
  matrix[5] = (coeff5.getProgress()-10)/div;
  matrix[6] = (coeff6.getProgress()-10)/div;
  matrix[7] = (coeff7.getProgress()-10)/div;
  matrix[8] = (coeff8.getProgress()-10)/div;
  
  textCoeff.setText(
   matrix[0] + " , " + matrix[1] + " , " + matrix[2] + " , \n" +
   matrix[3] + " , " + matrix[4] + " , " + matrix[5] + " , \n" +
   matrix[6] + " , " + matrix[7] + " , " + matrix[8]);
 }
 
 private Bitmap createBitmap_convolve(Bitmap src, float[] coefficients) {

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

  RenderScript renderScript = RenderScript.create(this);

  Allocation input = Allocation.createFromBitmap(renderScript, src);
  Allocation output = Allocation.createFromBitmap(renderScript, result);

  ScriptIntrinsicConvolve3x3 convolution = ScriptIntrinsicConvolve3x3
    .create(renderScript, Element.U8_4(renderScript));
  convolution.setInput(input);
  convolution.setCoefficients(coefficients);
  convolution.forEach(output);

  output.copyTo(result);
  renderScript.destroy();
  return result;
 }

}

<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidimageview.MainActivity" >

    <TextView
        android:id="@+id/title"
        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" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <SeekBar
            android:id="@+id/coeff0"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />

        <SeekBar
            android:id="@+id/coeff1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />

        <SeekBar
            android:id="@+id/coeff2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <SeekBar
            android:id="@+id/coeff3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />

        <SeekBar
            android:id="@+id/coeff4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="11" />

        <SeekBar
            android:id="@+id/coeff5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <SeekBar
            android:id="@+id/coeff6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />

        <SeekBar
            android:id="@+id/coeff7"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />

        <SeekBar
            android:id="@+id/coeff8"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="20"
            android:progress="10" />
    </LinearLayout>
    
    <SeekBar
            android:id="@+id/coeffdivby"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="19"
            android:progress="0" />
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        
        <Button
            android:id="@+id/blur"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Blur"/>
        <Button
            android:id="@+id/org"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Original"/>
        <Button
            android:id="@+id/sharpen"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Sharpen"/>
        
    </LinearLayout>
    
    <TextView
        android:id="@+id/textcoeff"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/image1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

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

</LinearLayout>



download filesDownload the files.