Android绘图机制二

ColorMatrix

Android对图片处理时,最常用的数据结构是Bitmap,整个图是由包含像素的点阵和对应透明度,红,绿,蓝的颜色值组成的,在Android中,系统使用ColorMatrix类来处理图像的色彩效果,ColorMatrix其实就是一个4x5颜色矩阵.

        imageView = (ImageView)findViewById(R.id.icon_group);
        ColorMatrix hueMatrix = new ColorMatrix();
        hueMatrix.setRotate(0,1);//设置颜色色调,分别使用 0 1 2来代表红 绿 蓝
        hueMatrix.setRotate(1,2);
        hueMatrix.setRotate(2,1);
        ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(0);//设置颜色的饱和度 0时,图像变为灰度
        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(0.33f,2f,91f,1);//设置图像的亮度 0时是全黑
        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);//将矩阵的作用混合,叠加处理效果
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);
        Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.meijing);
        Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
        canvas.drawBitmap(bm,0,0,paint);
        imageView.setImageBitmap(bitmap);
// 方式二 改变矩阵的系数来改变颜色
        Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.meijing);
        Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        float[] mColorMatrix = new float[20];
        for (int i = 0;i<20;i++){
            mColorMatrix[i]= Float.valueOf(String.valueOf(i));//改变矩阵的系数
        }
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.set(mColorMatrix);//将系数变化后的4x5的ARGB矩阵设置进去
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        canvas.drawBitmap(bm,0,0,paint);
        imageView.setImageBitmap(bitmap);

Matrix

Android对于图像的图形变换,通过一个3x3的矩阵来处理的,系统提供了Matrix类来处理图像的变形

        float[] mMatrix = new float[]{1,0,0,0,1,0,0,0,1};
        Matrix matrix = new Matrix();
        matrix.setValues(mMatrix);
        matrix.setTranslate(200,200);//图像平移
        matrix.setRotate(15);//图像旋转
        matrix.setSkew(15,15);//图像错切
        canvas.drawBitmap(bm,matrix,paint);//将图像以这个变换矩阵绘制出来
        imageView.setImageBitmap(bitmap);

Paint画笔特效

普通的Paint可以设置其变宽,填充的样式,颜色,宽度以及抗锯齿等基本属性,以下是画笔的高级属性
1 PorterDuffxfermode
PorterDuffxfermode设置的是两个图层交集区域的显示方式,用的最多的就是,使用一张图片作为另一张图片的遮罩层,通过控制遮罩层的图像,来展现不同的被遮罩图形的显示效果.
举例1 对图形进行圆角处理

        Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.meijing);
        Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawRoundRect(0,0,bm.getWidth(),bm.getHeight(),80,80,paint);//画一个半径为80的圆角的矩形长宽为bm.getWidth(),bm.getHeight()
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//给画笔添加模式为SRC_IN的PorterDuffXfermode
        canvas.drawBitmap(bm,0,0,paint);
        imageView.setImageBitmap(bitmap);

举例2 刮刮乐效果

    public XfermodeDemo(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setAlpha(0);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(50);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPath = new Path();
        mBgBitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.meijing);
        mbgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(),mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mbgBitmap);
        mCanvas.drawColor(Color.GRAY);
    }

    public XfermodeDemo(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBgBitmap,0,0,null);
        canvas.drawBitmap(mbgBitmap,0,0,null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("niuniu ", " onTouchEvent");
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mPath.reset();
                mPath.moveTo(event.getX(),event.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(event.getX(),event.getY());
                break;
        }

        mCanvas.drawPath(mPath,mPaint);
        invalidate();
        return true;
    }

2 Shader
Shader有着色器,渲染器之称,可以实现一些列渐变,渲染效果,包括以下几种:

  • BitmapShader ——— 位图Shader,与其他Shader产生的渐变不同的是,这个Shader是产生一个图像 有三种不同的模式 CLAMP(拉伸),REAPT(重复,横向,纵向不断的重复),MIRROR(镜像,横向/纵向不断翻转重复)
  • LinearGradient ——– 线性Shader
  • RadialGradient——– 光束Shader
  • SweepGradient——- - 梯度Shader
  • ComposeShader——- 混合Shader

举例1 BitmapShader的使用

        Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_android);
        Bitmap bitmap = Bitmap.createBitmap(800,800,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(bm, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
        canvas.drawCircle(180,200,100,paint);
        imageView.setImageBitmap(bitmap);

举例2 LinearGradient 的使用

        Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_android);
        Bitmap bitmap = Bitmap.createBitmap(800,800,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setShader(new LinearGradient(0,0,400,400,Color.BLUE,Color.YELLOW, Shader.TileMode.REPEAT));
        canvas.drawRoundRect(0,0,500,500,20,20,paint);
        imageView.setImageBitmap(bitmap);

举例3 LinearGradient 与 PorterDuffXfermode综合使用,实现倒影的效果

    public ReflectView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mBgBitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.arrow_right);
        Matrix matrix = new Matrix();
        matrix.setScale(1f,-1f);//对mBgBitmap实现垂直翻转
        mbgBitmap = Bitmap.createBitmap(mBgBitmap,0,0,mBgBitmap.getWidth(),mBgBitmap.getHeight(),matrix,true);
        mPaint = new Paint();
        mPaint.setShader(new LinearGradient(0,mBgBitmap.getHeight(),0,mBgBitmap.getHeight()+mBgBitmap.getHeight()/4,0XDD000000,0X10000000, Shader.TileMode.CLAMP));
        porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    }

    public ReflectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);//添加黑色背景
        canvas.drawBitmap(mBgBitmap,0,0,null);//画原图
        canvas.drawBitmap(mbgBitmap,0,mBgBitmap.getHeight(),null);//在原图的正下方画倒影图
        mPaint.setXfermode(porterDuffXfermode);
        canvas.drawRect(0,mBgBitmap.getHeight(),mbgBitmap.getWidth(),mBgBitmap.getHeight()*2,mPaint);//使用带有PorterDuffXfermode模式的并有线性渲染的画笔在原图正下方画出倒影效果
        mPaint.setXfermode(null);
    }

PathEffect

PathEffect就是对各种画笔设置不同的效果


// 初始化
        mPath = new Path();
        mPath.moveTo(0,0);
        for (int i =0;i<=30;i++){
            mPath.lineTo(i*35,(float) Math.random()*100);
        }
    //添加不同画笔效果
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mEffects[0]=null;// 没任何效果
        mEffects[1]= new CornerPathEffect(30);//将拐角处处理的圆滑一些
        mEffects[2]= new DiscretePathEffect(3.0F,5.0F);//在线段上产生一些杂点
        mEffects[3]= new DashPathEffect(new float[]{20,10,5,10},0);//绘制虚线,数组代表各个点之间的间隔,另一个是参数偏移量
        Path path = new Path();
        path.addRect(0,0,100,100,Path.Direction.CCW);
        mEffects[4] = new PathDashPathEffect(path,12,0, PathDashPathEffect.Style.ROTATE);//也是设置虚线的效果,但可以设置点的图形,比如方形点 圆形点
        mEffects[5]= new ComposePathEffect(mEffects[3],mEffects[1]);//将这两种效果组合起来
        for (int i = 0;i<mEffects.length;i++){
            mPaint.setPathEffect(mEffects[i]);
            canvas.drawPath(mPath,mPaint);
            canvas.translate(0,200);
        }
    }

猜你喜欢

转载自blog.csdn.net/dakaniu/article/details/78856355