图片画画板

1、为自定义View画空白图

 @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mBimap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);//当该View尺寸发生改变的时候执行
            canvas = new Canvas(mBimap);
        }

2、为自定义View设置触摸事件

 @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();//event.getRawX()相对手机屏幕的坐标,event.getX()为相对于ImageView的坐标
            float y = event.getY();
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    touchDown(x,y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touchMove(x,y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touchUp(x,y);
                    invalidate();//对该View进行刷新
                    break;
            }
            return true;
        }

        private void touchUp(float x, float y) {
            mPath.lineTo(mX,mY);
            canvas.drawPath(mPath, mPaint);
            //清空path
            mPath.reset();
        }

        private void touchMove(float x, float y) {
            mPath.quadTo(mX,mY,x,y);
            canvas.drawPath(mPath,mPaint);
            mX = x;
            mY = y;
        }

        private void touchDown(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }
tips:  moveTo、lineTo、quadTo、cubicTo、arcTo的作用 https://segmentfault.com/a/1190000000721127

 3、设置画笔的颜色、浮雕、模糊效果

mPaint = new Paint();
        mPaint.setAntiAlias(true);//抗锯齿
        mPaint.setDither(true);//开启抖动
        mPaint.setColor(0xFFFF0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);//设置结合处的样子
        mPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔笔刷的类型
        mPaint.setStrokeWidth(12);

        /**
         direction 是float数组,定义长度为3的数组标量[x,y,z],来指定光源的方向
         ambient 取值在0到1之间,定义背景光 或者说是周围光
         specular 定义镜面反射系数。
         blurRadius 模糊半径。
         */
        mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
                0.4f, 6, 3.5f);
        /**
         * radius 模糊的半径
         * style 模糊的样式
         */
        mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);


 @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        mPaint.setXfermode(null);
        mPaint.setAlpha(0xFF);
        switch (item.getItemId()){
            case R.id.menu_color:
                break;
            case R.id.menu_emboss:
                if(mPaint.getMaskFilter() != mEmboss){
                    mPaint.setMaskFilter(mEmboss);
                }else{
                    mPaint.setMaskFilter(null);
                }
                break;
            case R.id.menu_blur:
                if(mPaint.getMaskFilter() != mBlur){
                    mPaint.setMaskFilter(mBlur);
                }else{
                    mPaint.setMaskFilter(null);
                }
                break;
            case R.id.menu_ease:
                mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                break;
            case R.id.menu_srcatop:
                mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
                mPaint.setAlpha(0x80);
                break;
        }
        return true;
    }

在Android4.0以上可能看不到浮雕、模糊效果,需要在该Activity设置android:hardwareAccelerated="false"

最后保存图片

FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,80,outputStream);
outputStream.close();

保存之后并不能在图库中看到,在这里要需要通知SDCard重新挂载

由于在KITKAT版本,查看core/res/AndroidManifest.xml你将注意到那个广播android.intent.action.MEDIA_MOUNTED是被保护的,那将意味着他是一个仅仅被系统可以发送的广播

<protected-broadcast android:name="android.intent.action.MEDIA_MOUNTED" />

因此你需要使用其它的方法来fix it,像ACTION_MEDIA_SCANNER_SCAN_FILE或者MediaScannerConnection

Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);

或者

MediaScannerConnection.scanFile(this, new String[]{file.getAbsolutePath()}, null, new MediaScannerConnection.MediaScannerConnectionClient() {
    @Override
    public void onMediaScannerConnected() {

    }

    @Override
    public void onScanCompleted(String path, Uri uri) {
    }
});
使用Intent.ACTION_MEDIA_SCANNER_SCAN_FILE适用于所有的版本,而MediaScannerConnnetion只能用在Android2.3之后。
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    Intent mediaScanIntent = new Intent(
                            Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    Uri contentUri = Uri.fromFile(out); \\out is your output file
                    mediaScanIntent.setData(contentUri);
                    this.sendBroadcast(mediaScanIntent);
                } else {
                    sendBroadcast(new Intent(
                            Intent.ACTION_MEDIA_MOUNTED,
                            Uri.parse("file://"
                                    + Environment.getExternalStorageDirectory())));
                }


你可能感兴趣的:(android)