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);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章