[android] 05_图片画画板(类似QQ涂鸦)并保存图片到SDcard

Android 4.0

        Intent in = new Intent();
        in.setAction(Intent.ACTION_MEDIA_MOUNTED);
        in.setData(Uri.fromFile(Environment.getRootDirectory()));
        this.sendBroadcast(in);

        // 从图库中选择一张图片
        Intent intent = new Intent();
        intent.setAction("android.intent.action.PICK");
        intent.setType("image/*");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        this.startActivityForResult(intent, 0); 图库只有在重启后才会遍历sdcard中的内容,或者在sdcard被拔出来和插进去会遍历里面的内容
所以我们需要发送一个装载sd卡挂载操作的广播

package cn.zengfansheng.paint;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
 
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.Toast;
 
public class MainActivity extends Activity {
 
    private ImageView iv;
    private Canvas canvas;
    private Paint paint;
    private Bitmap mutableBitmap;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) this.findViewById(R.id.iv);
 
        // TODO 给图片注册一个手指的触摸事件, 触摸屏幕的时候 根据手指的变化 画线
        iv.setOnTouchListener(new OnTouchListener() {
 
            private int startX;// 开始x坐标
            private int startY;// 开始y坐标
            @Override
            public boolean onTouch(View v, MotionEvent event) {
 
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:// 手指第一次触摸到屏幕
                    System.out.println("摸到了。。。");
                    startX = (int) event.getX();
                    startY = (int) event.getY();
                    break;
                case MotionEvent.ACTION_UP:// 手指离开屏幕一瞬间
                    System.out.println("松手了。。。");
                    break;
                case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动
                    System.out.println("移动了。。。");
                    int newX = (int) event.getX();
                    int newY = (int) event.getY();
                    System.out.println("画线:("+startX+","+startY+")~~("+newX+","+newY+")");
                    canvas.drawLine(startX, startY, newX, newY, paint);
 
                    // 重新更新开始坐标
                    startX = (int) event.getX();
                    startY = (int) event.getY();
                    iv.setImageBitmap(mutableBitmap);
                    break;
                }
                return true;// FIXME true,消费掉该事件,false,反之。
            }
        });
    }
 
    /**
     * TODO 一、从图库中选择一张图片
     * @param view
     */

    public void pick(View view){
        // 模拟一个操作,重新装载sd卡的动作
        Intent in = new Intent();
        in.setAction(Intent.ACTION_MEDIA_MOUNTED);
        in.setData(Uri.fromFile(Environment.getRootDirectory()));
        this.sendBroadcast(in);
        // 从图库中选择一张图片
        Intent intent = new Intent();
        intent.setAction("android.intent.action.PICK");
        intent.setType("image/*");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        this.startActivityForResult(intent, 0);
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data != null) {
            try {
                // TODO 获取要查看的图片的路径 Uri(Immutable URI reference)
                Uri uri = data.getData();
 
                // 得到从图库中选择的图片做背景,但只是一个只读的Bitmap,不可编辑
                InputStream is = this.getContentResolver().openInputStream(uri);
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                // 创建一个可以编辑的Bitmap
                mutableBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
 
                // TODO 1、创建一个画布,以一个指定的bitmap为背景// 2、在画布上画背景
                canvas = new Canvas(mutableBitmap);// The bitmap must be mutable
 
                // TODO 3、创建一支画笔,并设置相应的参数
                paint = new Paint();
                paint.setColor(Color.RED);
                paint.setStrokeWidth(8);
 
                // FIXME 为啥是原来的bitmap4、参考着 原图 bitmap 把内容画在 alterbitmap
                canvas.drawBitmap(bitmap, new Matrix(), paint);
 
                // 5、
                iv.setImageBitmap(mutableBitmap);
            } catch (Exception e) {
                e.printStackTrace();
            }
 
        }
    }
    /**
     * TODO 二、保存涂鸦修改后的图片到sdcard
     * @param view
     */

    public void save(View view){
        try {
            File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
            FileOutputStream fos = new FileOutputStream(file);
            mutableBitmap.compress(CompressFormat.JPEG, 100, fos);
            Toast.makeText(getApplicationContext(), "保存成功", 1).show();
            fos.close();
            // 模拟一个重新插入sd卡的操作
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
            intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
            sendBroadcast(intent);
        } catch (IOException e) {
            Toast.makeText(this, "保存失败", 1).show();
            e.printStackTrace();
        }
    }
}