• canvas 的cliprect()实现画布剪切DEMO


    canvas 的cliprect()能够对画布实现剪切,显示需要的可见区域,除了此区域之外的地方其任何内容都不可见,这个区域可以是矩形也可以是圆。

    这个demo简单用了一张图片在画布中使用cliprect方法剪切了一部分,需要注意的是要用到 save()和restore()两个成对出现的方法!其实对剪切的操作就是在这两个方法之间进行的,简单的说就是在cliprect设置了可见区域后,在这个可见区域内进行的操作能够保留下来,不在这个区域内操作的东西通过restore()方法就把它“清除掉了”

    public class MSurfaceView extends SurfaceView implements Callback, Runnable{
        
        private SurfaceHolder holder;
        private Paint paint, paintFont;
        private Thread mThread;
        private Canvas canvas;
        private boolean state;
        private int x, y;
        private int window_x, window_y;
        private final static int MAX_TIME = 80;
        private Bitmap mBitmap, backBitmap;
        
        public MSurfaceView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            holder = this.getHolder();
            paint = new Paint();
            paintFont = new Paint();
            paint.setColor(Color.BLUE);
            paintFont.setColor(Color.WHITE);
            holder.addCallback(this);
            setFocusable(true);
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
            // TODO Auto-generated method stub
            Log.v("tag", "surfacechanged");
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            Log.v("tag", "surfacecreated");
            window_x = this.getWidth();
            window_y = this.getHeight();
            state = true;
            mThread = new Thread(this);
            mThread.start();
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            Log.v("tag", "surfacedestoryed");
            state = false;
        }
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub
            x = (int)event.getX();
            y = (int)event.getY();
            return true;
        }
        public void mDraw(){
            try {
                canvas = holder.lockCanvas();
    //            if (canvas != null) {
    //                backBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.okc);
    //                canvas.drawBitmap(backBitmap, 0, 0, paint);
                    canvas.drawRGB(0, 0, 0);
                    mBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher);
                    canvas.drawBitmap(mBitmap, x, y, paint);
                    Log.v("tag", "绘制位图");
                    canvas.save();
                    canvas.clipRect(0, 0, 200, 200);
                    backBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.okc);
                    canvas.drawBitmap(backBitmap, 0, 0, paint);
    //                canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);
    //                canvas.translate(10, 10);
    //                canvas.drawBitmap(mBitmap, 50, 50, paint);
                    canvas.restore();
    //                canvas.drawCircle(x, y, getradius(), paint);
    //                canvas.drawText("坐标值:" + x, 30, 30, paintFont); 
    //                canvas.drawText("坐标值:" + y, 40, 40, paintFont); 
    //            }
            } catch (Exception e) {
                // TODO: handle exception
            }finally{
                if (canvas != null) {
                    holder.unlockCanvasAndPost(canvas);
                }
            }
        }
        private int getradius(){
             int r = (int)(Math.random()*30);
             return r;
        }
    
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(state){
                long start = System.currentTimeMillis();
                mDraw();
                long end = System.currentTimeMillis();
                if ((end - start) < MAX_TIME) {
                    try {
                        Thread.sleep(MAX_TIME - (end - start));
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }

    用MainActivity.java显示当前的view:

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(new MSurfaceView(this));
        }
        
        
    }

    第一张时剪切后的效果,第二张是原始图片

    哈哈哈 图片有点太大了 没管那么多

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    下面再通过另外一种方式实现画布剪切,这次剪切一个圆形区域,使用path:

    canvas.save();
                    Path path = new Path();
                    path.addCircle(40, 50, 30, Direction.CCW);
                    canvas.clipPath(path);
                    backBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.okc);
                    canvas.drawBitmap(backBitmap, 0, 0 ,paint);
    canvas.restore();

    首先实例化path,然后添加一个指定大小的circle并将这个circle作为我们所要的可见区域,再在屏幕上面绘制我们的图片,然后使用restore方法,“清除”掉我们绘制时候没有在可见区域内的操作,最后看到的效果如下:

  • 相关阅读:
    母函数详解
    java中为什么要实现序列化,什么时候实现序列化?
    cocos2dx&cocosbuilder折腾记
    Unity3D系列教程–使用免费工具在Unity3D中开发2D游戏 第二节(下)
    分頁查詢
    獲取CPU,硬盤序列號
    spcomm
    dbgrideh的導入和導出
    程序窗体及控件自适应分辨率
    組合的藝術
  • 原文地址:https://www.cnblogs.com/tiejiangweigaibianercunzai/p/3897238.html
Copyright © 2020-2023  润新知