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

好吧,关于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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。