Android图像处理技术(实现Android中的PS)(六)

来源:互联网 发布:西雅图必去景点知乎 编辑:程序博客网 时间:2024/04/30 15:26

好吧,关于Android中图像处理的最后一个微博,保证是最后一个了,希望泥萌不要骂我。。。

今天想实现的效果是:终极大招:利用BitmapMesh来实现一些特效。
当然,BitmapMesh功能十分强大,打开大家的脑洞,相信大家会设计出更炫丽的特效:

和往常一样,首先,上效果图,卖个萌:
这里写图片描述
怎么样,普通的一张图按正弦曲线跳起舞来了。。。

然后,开始吧:

首先,自定义View:BitmapMeshView:

public class BitmapMeshView extends View {    //后面跳舞的那张图片    private Bitmap mBitmap;    //每个格子的宽度    private int WIDTH = 200;    //每个格子的高度    private int HEIGHT = 200;    //交点的总个数,比如说一个三行三列的表格,共有4*4=16个节点,不信自己数数看    private int COUNT = (WIDTH + 1) * (HEIGHT + 1);    //用来存放更改后的每个点的坐标:说明一点,这里我们用连续的两个点表示一个坐标:    //比如说verts[0]和verts[1]联合表示第一个节点坐标,verts[2]和verts[3]联合表示第二个节点坐标,以此类推    private float verts[] = new float[COUNT * 2];    private float origs[] = new float[COUNT * 2];    //更改前每个点的坐标    private float k = 0;    //第几个点    private int index=0;    //不说了。。    public BitmapMeshView(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    private void initView() {        //从资源中加载一张图片        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);        //得到图片的宽和高        float bmWidth = mBitmap.getWidth();        float bmHeight = mBitmap.getHeight();        //遍历所有节点,记录所有点的坐标:        for (int i = 0; i < HEIGHT + 1; i++) {            //得到当前节点的Y轴坐标:Y轴坐标就是当当前行中所占的比例,好好想想,不难            float fy = bmHeight * i / HEIGHT;            for (int j = 0; j < WIDTH + 1; j++) {                //得到当前节点的X轴坐标:X轴坐标就是当当前行中所占的比例,                float fx=bmWidth*j/WIDTH;                //获得原始坐标,想想就知道了                origs[index*2+0]=verts[index*2+0]=fx;                //提一下:这里fy+50是让图片往下平移一段距离,让图片在跳舞时不至于跳出屏幕外边去                origs[index*2+1]=verts[index*2+1]=fy+50;                index++;            }        }    }    @Override    protected void onDraw(Canvas canvas) {        //这个双层循环是从上面直接复制过来的,改一下中间的内容就行了        for (int i = 0; i < HEIGHT + 1; i++) {            for (int j = 0; j < WIDTH + 1; j++) {                //我们想实现的效果的本质是:x轴坐标不动,y轴坐标按正弦规律变化,所以我们只需要计算Y轴偏移量                //下面这个偏移量看似很复杂,其实很简单:                /**                 * 解释一下offset:  这其实是个标准的正弦表达式: Y=A*sin(w*x+&)+h;                 * 是不是很熟悉(有两个符号不好打,直接用其他符号代替的,,,总之这不重要)                 * 我们来对号入座:                  * A=20                 * &=k;                 * h=0;                    * w=1/WIDTH*2*Math.PI                 * x=j                 * 然后想一下w为啥是1/WIDTH*2*Math.PI,这个不难吧                 */                float offSet=(float)Math.sin((float)j/WIDTH*2*Math.PI+k)*20;                //更改Y坐标:在原来的基础上加上一个offSet;                verts[(i*(WIDTH+1)+j)*2+1]=origs[(i*(WIDTH+1)+j)*2+1]+offSet;            }        }        //让相位K递增        k+=0.2F;        //绘图        canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, verts, 0, null, 0, null);        //再次调用onDraw()方法,更新Y坐标        invalidate();    }}

花了好长时间注释,应该是讲明白了,不明白的请留言,我会及时回复的。

当然,我们实现的效果知识一个小例子,希望本博客能够抛砖引玉,或者能给你些许启发,相信加上你聪慧的大脑,肯定能编写出更加绚丽的效果。

技术是死的,人是活的。。

好了,终于要结束了,希望能给各位朋友一些启发,那我就非常高兴了。

最后,Demo地址:http://download.csdn.net/detail/nsgsbs/8540553

0 0