使用


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

public class MainActivity extends Activity {
    float blurRadius = 5f;//在使用光之前的模糊不清的面具的宽度。
    private DrawView drawView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        drawView = new DrawView(this);
        setContentView(drawView);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.red:
            drawView.getPaint().setColor(Color.RED);
            break;
        case R.id.blue:
            drawView.getPaint().setColor(Color.BLUE);
            break;
        case R.id.green:
            drawView.getPaint().setColor(Color.GREEN);
            break;
        case R.id.width_3:
            drawView.getPaint().setStrokeWidth(dp2px(3));
            break;
        case R.id.width_6:
            drawView.getPaint().setStrokeWidth(dp2px(6));
            break;
        case R.id.emboss://浮雕效果
            drawView.getPaint().setMaskFilter(new EmbossMaskFilter(new float[] { 0.5f, 1f, 1.5f }, 0.6f, 5f, blurRadius));
            //float[] direction 用来指示光源照的方向;float ambient 光的强度系数;float specular 镜子的高亮系数;float blurRadius 在使用光之前的模糊不清的面具的宽度
            break;
        case R.id.blur://模糊效果
            blurRadius = drawView.getPaint().getStrokeWidth();
            drawView.getPaint().setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));
            break;
        case R.id.save:
            Bitmap bitmap = drawView.getCacheBitmap();
            if (bitmap != null) saveBitmap2Pic(bitmap);
            else Toast.makeText(this, "保存失败", Toast.LENGTH_SHORT).show();
            break;
        default:
            break;
        }
        return true;
    }

    /** 
    * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
    */
    public int dp2px(float dpValue) {
        float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
    /** 保存bitmap为图片 */
    public void saveBitmap2Pic(Bitmap bitmap) {
        File file = new File(Environment.getExternalStorageDirectory(), new SimpleDateFormat("yyyy.MM.dd HH-mm-ss", Locale.getDefault()).format(new Date()) + ".png");
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            Toast.makeText(this, "保存出现异常", Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
}


View

public class DrawView extends View {
    private float preX;//前一个点的(x,y)坐标
    private float preY;
    private Path path;
    private Bitmap cacheBitmap = null; //最核心的地方。定义一个内存中的图片,将图片作为缓冲区。大小为屏幕宽高的大小。
    private Canvas cacheCanvas = null; //定义cacheBitmap的画布
    private Paint cachePaint = null;//定义cacheBitmap的画笔
    public Bitmap getCacheBitmap() {
        return cacheBitmap;
    }
    public Paint getPaint() {
        return cachePaint;
    }

    public DrawView(Context context) {
        this(context, null);
    }
    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        cacheBitmap = Bitmap.createBitmap(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels, Config.ARGB_8888);  
         cacheCanvas = new Canvas(cacheBitmap);
        path = new Path();
        cachePaint = new Paint();
        cachePaint.setColor(Color.BLACK);
        cachePaint.setStyle(Paint.Style.STROKE);
        cachePaint.setStrokeWidth(1 * context.getResources().getDisplayMetrics().density + 0.5f);//1dp
        cachePaint.setAntiAlias(true);
        cachePaint.setDither(true);
    }

    @SuppressLint("ClickableViewAccessibility")
    //意思是:有可能会和点击事件发生冲突,如果你在touch中返回了true,那么就不会响应onClick事件了
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(x, y);
            preX = x;
            preY = y;
            break;
        case MotionEvent.ACTION_MOVE:
            path.quadTo(preX, preY, x, y);//平滑的"贝塞尔曲线"(Bezier curve)。其中,x1,y1为控制点的坐标值,x2,y2为终点的坐标值;
            //path.lineTo(preX, preY);//由于onTouchEvent事件回调非常频繁,所以用lineTo方法也是可以的
            preX = x;
            preY = y;
            break;
        case MotionEvent.ACTION_UP:
            cacheCanvas.drawPath(path, cachePaint);//当手指移开时,把曲线画到cacheCanvas中,在onDraw中又把cacheCanvas画到我们的自定义View中。
            path.reset();
            break;
        default:
            break;
        }
        invalidate();
        return true;
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(cacheBitmap, 0, 0, cachePaint);
        canvas.drawPath(path, cachePaint);
    }
}


菜单

<!-- <menu>标签是根元素,他没有属性,在<menu>里面可嵌套<item>和<group>子元素 -->
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- <item>标签表示具体的菜单项,<item>元素中也可嵌套<menu>形成子菜单 -->
    <item android:title="选择颜色">
        <menu>
            <!-- <group>标签表示一个菜单组,相同的菜单组可以一起设置其属性,checkableBehavior:选择行为:单选、多选 -->
            <group android:checkableBehavior="single" >
                <item
                    android:id="@+id/red"
                    android:title="红色"/>
                <item
                    android:id="@+id/green"
                    android:title="绿色"/>
                <item
                    android:id="@+id/blue"
                    android:title="蓝色"/>
            </group>
        </menu>
    </item>
    <item
        android:id="@+id/width_3"
        android:title="3dp"/>
    <item
        android:id="@+id/width_6"
        android:title="6dp"/>
    <item
        android:id="@+id/blur"
        android:title="模糊效果"/>
    <item
        android:id="@+id/emboss"
        android:title="浮雕效果"/>
    <item
        android:id="@+id/save"
        android:title="保存为图片"/>
</menu>


画画 保存为图片 MaskFilter 边缘效果的更多相关文章

  1. iOS图片加水印效果的实现并保存至相冊

    图片加水印效果的实现并保存至相冊 实现效果如图: project下载:githubproject下载链接 代码: - (void)viewDidLoad { [super viewDidLoad]; ...

  2. JQuery图片切换动画效果

    由于博主我懒,所以页面画的比较粗糙,但是没关系,因为我主要讲的是如何实现图片动画切换. 思路:想必大家都逛过淘宝或者其他的一些网站,一般都会有图片动画切换的效果,那是怎样实现的呢?博主我呢,技术不是很 ...

  3. ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave由于鼠标移动速度过快导致问题解决办法

    记录两个项目开发中遇到的问题,一个是ECharts外部调用保存为图片操作,一个是workflow工作流连接曲线onmouseenter和onmouseleave事件由于鼠标移动过快触发问题. 一.外部 ...

  4. CSS鼠标悬停图片加边框效果,不位移的方法

    <!DOCTYPE HTML> <html lang="en-US"> <head> <title>css实现鼠标悬停时图片加边框效 ...

  5. 用仿ActionScript的语法来编写html5——第八篇,图片处理+粒子效果

    用仿ActionScript的语法来编写html5系列开发到现在,应该可以做出一些东西了,下面先来研究下图片的各种效果预览各种效果看下图效果和代码看这里,看不到效果的请下载支持html5的浏览器 ht ...

  6. h5页面使用js实现保存当前图片到手机相册

    很可惜,这个鬼东西微信内置浏览器不适用 页面: <!doctype html> <html> <head> <meta charset="UTF-8 ...

  7. js生成二维码并保存成图片下载

    我这里使用是jQuery,和jquery.qrcode.js,需要的可以自己找链接下载.示例代码仅做参考 html代码: <a id="downloadLink">&l ...

  8. Android中使用MediaCodec硬件解码,高效率得到YUV格式帧,快速保存JPEG图片(不使用OpenGL)(附Demo)

    MediaCodec的使用demo: https://github.com/vecio/MediaCodecDemo https://github.com/taehwandev/MediaCodecE ...

  9. 利用LruCache载入网络图片实现图片瀑布流效果(改进版)

    PS: 2015年1月20日21:37:27 关于LoadImageAsyncTask和checkAllImageViewVisibility可能有点小bug 改动后的代码请參见升级版本号的代码 ht ...

随机推荐

  1. 纯js制作遮罩层对话框 -- g皓皓

    //本文支持js在线工具测试.转载请注明出处. <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> < ...

  2. 初涉JavaScript模式系列 阶段总结及规划

    总结 不知不觉写初涉JavaScript模式系列已经半个月了,没想到把一个个小点进行放大,竟然可以发现这么多东西. 期间生怕对JS的理解不到位而误导各位,读了很多书(个人感觉JS是最难的oo语言),也 ...

  3. python抓取网页图片

    本人比较喜欢海贼王漫画,所以特意选择了网站http://www.mmonly.cc/ktmh/hzw/list_34_2.html来抓取海贼王的图片. 因为是刚刚学习python,代码写的不好,不要喷 ...

  4. zsh中home键失灵问题

    putty访问linux时,如果出现这个情况,可以更改配置中Connection->Data->Terminal-type-string,改为linux,再连接即可 mac下可打开终端的配 ...

  5. APP如何设计才能适配iphone6/plus和iphone5

    随着苹果发布两种新尺寸的大屏iPhone 6,iOS平台尺寸适配问题终于还是来了,移动设计全面进入"杂屏"时代.看看下面三款iPhone尺寸和分辨率数据就知道屏幕有多杂了. 移动a ...

  6. 习题二:string数组应用

    说明: 读字符串char buf[100]="xxx:yyy:zzz:aaa:bbb" 按“:”进行分解到string数组中去 逻辑: 通过指针遍历整个字符串 遇到'\0'表示字符 ...

  7. java的占位符

    java占位符的类型: 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.fo ...

  8. HID燈是什么及其工作原理

    HID為HighIntensityDischarge的縮寫,即高壓氣體放電燈,它發光的原理是將12V電壓增壓至23000V的超高電壓,激穿填充在石英管的氙氣,使它發光.然后再將電壓轉成85V左右,穩定 ...

  9. WordPress NextGEN Gallery ‘upload.php’任意文件上传漏洞

    漏洞名称: WordPress NextGEN Gallery ‘upload.php’任意文件上传漏洞 CNNVD编号: CNNVD-201306-259 发布时间: 2013-06-20 更新时间 ...

  10. 【转】 Android 基于google Zxing实现对手机中的二维码进行扫描--不错

    原文网址:http://blog.csdn.net/xiaanming/article/details/14450809 转载请注明出处:http://blog.csdn.net/xiaanming/ ...