栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android Paint 抗锯齿画线模糊

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android Paint 抗锯齿画线模糊

背景

Android 开发过程中, 或多或少会遇到需要使用自定义控件的情况, 而Paint作为画笔, 在整个开发过程中有着至关重要的地位, 用好它, 能让自定义控件展示出你期望的效果, 用不好… 或许会抱怨, 这平台/这工具/这类怎么设计得如此难用.

就如同本文将要阐述的问题, 希望能给遇到相似问题的朋友一点帮助, 若无碰到此类问题, 请自行略过.

问题

先看一张效果图 (图1):

两个网图, 同样设置的笔画宽度为1 setStrokeWidth(1), 左边的显示的大小是正常的, 右边则变成了2. 颜色也淡了.

下面这张图看起来会很明显,(一个方格为一个PIXEL) (图2):

而程序设计时, 所期望的效果是: (图3):

WHY

大概也猜到了, 这可能跟设置了抗锯齿有关, 没错, 确实的这样子

        Paint paint;
        Paint paintAnti;
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            //无抗锯齿
            paint = createPaint(false, Color.GREEN);
            //设置了抗锯齿
            paintAnti = createPaint(true, Color.RED);
        }
        Paint createPaint(boolean anti, int color){
            Paint paint = new Paint(anti ? Paint.ANTI_ALIAS_FLAG : 0);
            paint.setColor(color);
            paint.setStyle(Paint.Style.STROKE);
            //设置同样的宽度.
            paint.setStrokeWidth(1);
            return paint;
        }
    

创建画笔的唯一区别就是设置了Paint.ANTI_ALIAS_FLAG, 那么这个问题其实很好解决, 把抗锯齿关了就可以了.

确实是这样.


继续

同样上面的红网模糊的代码, 加入一个功能, 通过触摸更新红网的位置,

		//添加直线.
        void addLine(Path p, float fx, float fy, float tx, float ty){
            p.moveTo(fx + startX, fy + startY);
            p.lineTo(tx + startX, ty + startY);
        }
		//更新Path.
        void update(){
            pathAnti.reset();
            float left = 60;
            float right = 110;
            float top = 0;
            float bottom = 0;
            for(int i = 1; i < 10; i ++) {
                top = bottom = i * interval;
                addLine(pathAnti, left, top, right, bottom);
            }
            top = 0;
            bottom = 50;
            for(int i = 1; i < 10; i ++) {
                left = right = 60 + i * interval;
                addLine(pathAnti, left, top , right, bottom);
            }
        }

        float startX, startY;
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            startX = event.getX()/30f;
            startY = event.getY()/30f;
            update();
            postInvalidate();
            return true;
        }

通过不停的触摸不同的位置并观察红网的效果, 发现一个现象,
当startX/startY的值, 去掉整数后, 剩下的小数值, 越接近0.5, 则线越实, 越接近期望的效果.

最接近期望效果 图4

于是, addLine稍微修改下:

        void addLine(Path p, float fx, float fy, float tx, float ty){
        	//取整, 再加上0.5, 得到的结果永远是 x.5;
            fx = (int)(fx + startX) + 0.5f;
            tx = (int)(tx + startX) + 0.5f;
            fy = (int)(fy + startY) + 0.5f;
            ty = (int)(ty + startY) + 0.5f;
            p.moveTo(fx, fy);
            p.lineTo(tx, ty);
        }

不管如何更新坐标, 显示的效果都如下图: 图5

			DashPathEffect dpe = new DashPathEffect(new float[]{3, 4}, 0);
            paint.setPathEffect(dpe);
            paintAnti.setPathEffect(dpe);

画个虚线 图6

最后

有点遗憾问题并不能够完美解决. 要能够彻底弄清楚是何原理, 估计得花不少精力去研究系统源码, 暂时没这时间精力, 只能听之任之, 坐等精于此道的先行者指点谜津. 共勉!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/685869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号