图像处理2 --图像形状




1.通过坐标变换矩阵 去改变图像的形状大小位置等 (9位 float)




    A  B C

    D E F

    G H I                          --> AE控制缩放,CF控制平移, BD控制错切




2.  android API操作


matrix.setRote(); -- 旋转

matrix.setTranslate() -- 平移

matrix.setScale() -- 缩放

matrix.setSkew() -- 错切

post -- 矩阵组合



3.     通过画笔风格实现不同图形特效   -Xfermode

PorterDuff.Mode为枚举类,一共有16个枚举值:

1.PorterDuff.Mode.CLEAR  

  所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC

   显示上层绘制图片
3.PorterDuff.Mode.DST

  显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER

  正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER

  上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN

   取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN

  取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT

 取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT

 取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP

 取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP

 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR

  异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN

  取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN

  取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY

  取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN

  取两图层全部区域,交集部分变为透明色





事例 做一个四周有圆角的图形:

public class RoundRectXfermodeView extends View {


    private Bitmap mBitmap;
    private Bitmap mOut;
    private Paint mPaint;


    public RoundRectXfermodeView(Context context) {
        super(context);
        initView();
    }


    public RoundRectXfermodeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }


    public RoundRectXfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }


    private void initView() {
        setLayerType(LAYER_TYPE_SOFTWARE, null);    //    要禁用 硬件加速 
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
        mOut = Bitmap.createBitmap(mBitmap.getWidth(),
                mBitmap.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mOut);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // Dst  遮罩层
        canvas.drawRoundRect(0, 0, mBitmap.getWidth(), mBitmap.getHeight(),
                50, 50, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  // 设置画笔的 xfermode属性为  src_in
        // Src
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        mPaint.setXfermode(null);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mOut, 0, 0, null);
    }
}






4.   画笔风格-  shader  着色器/渲染器  

      图像渐变:   BitmapShader


public   BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)

调用这个方法来产生一个画有一个位图的渲染器(Shader)。

bitmap   在渲染器内使用的位图

tileX      The tiling mode for x to draw the bitmap in.   在位图上X方向渲染器平铺模式

tileY     The tiling mode for y to draw the bitmap in.    在位图上Y方向渲染器平铺模式

TileMode:

CLAMP  :如果渲染器超出原始边界范围,会复制范围内边缘染色。

REPEAT :横向和纵向的重复渲染器图片,平铺。

MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。


示例:


package com.tony.shader;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;


public class BitmapShaderView extends View {


private BitmapShader bitmapShader = null;
private Bitmap bitmap = null;
private Paint paint = null;
private ShapeDrawable shapeDrawable = null;
private int BitmapWidth = 0;
private int BitmapHeight = 0;


public BitmapShaderView(Context context) {
super(context);


// 得到图像
bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.cat))
.getBitmap();
BitmapWidth = bitmap.getWidth();
BitmapHeight = bitmap.getHeight();
// 构造渲染器BitmapShader
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR,Shader.TileMode.REPEAT);
}

public BitmapShaderView(Context context,AttributeSet set) {
super(context, set);
}


@Override
protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
super.onDraw(canvas);
//将图片裁剪为椭圆形    
        //构建ShapeDrawable对象并定义形状为椭圆    
        shapeDrawable = new ShapeDrawable(new OvalShape());  
        //得到画笔并设置渲染器  
        shapeDrawable.getPaint().setShader(bitmapShader);  
        //设置显示区域  
        shapeDrawable.setBounds(20, 20,BitmapWidth-140,BitmapHeight);  
        //绘制shapeDrawable  
        shapeDrawable.draw(canvas);  
}


}






5. 像素块   drawBitmapMesh


public class MeshView extends View {


    private int WIDTH = 200;
    private int HEIGHT = 200;
    private int COUNT = (WIDTH + 1) * (HEIGHT + 1);
    private float[] verts = new float[COUNT * 2];
    private float[] orig = new float[COUNT * 2];
    private Bitmap mBitmap;
    private float K = 1;


    public MeshView(Context context) {
        super(context);
        initView();
    }


    public MeshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }


    public MeshView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }


    private void initView() {
        int index = 0;
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
        float bmWidth = mBitmap.getWidth();
        float bmHeight = mBitmap.getHeight();


        for (int i = 0; i < HEIGHT + 1; i++) {
            float fy = bmHeight * i / HEIGHT;
            for (int j = 0; j < WIDTH + 1; j++) {
                float fx = bmWidth * j / WIDTH;
                orig[index * 2 + 0] = verts[index * 2 + 0] = fx;
                orig[index * 2 + 1] = verts[index * 2 + 1] = fy + 200;
                index += 1;
            }
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        for (int i = 0; i < HEIGHT + 1; i++) {
            for (int j = 0; j < WIDTH + 1; j++) {
                verts[(i * (WIDTH + 1) + j) * 2 + 0] += 0;
                float offsetY = (float) Math.sin((float) j / WIDTH * 2 * Math.PI + K * 2 * Math.PI);
                verts[(i * (WIDTH + 1) + j) * 2 + 1] =
                        orig[(i * (WIDTH + 1) + j) * 2 + 1] + offsetY * 50;
            }
        }
        K += 0.1F;
        canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT,
                verts, 0, null, 0, null);
        invalidate();
    }
}


   



      




你可能感兴趣的:(图像处理2 --图像形状)