自定义控件-截屏当前界面

来源:互联网 发布:情义我心知 编辑:程序博客网 时间:2024/06/05 16:55

声明一下先贴出的一个图片裁剪的类,忘记是从哪位大神那拿的代码了,见谅哈!如果有人知道的话,回复一下链接,我再补上,哈哈...

看下效果:

以下是在图片裁剪类的原型上修改过的:

import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Rect;import android.graphics.Region;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import com.hmy.android.allforme.util.DimenUtil;/** * Created by hmy  */public class CropImageView extends View {    protected Context mContext;    private DimenUtil dimenUtil;    // 在touch重要用到的点,    private float mX_1 = 0;    private float mY_1 = 0;    // 当前状态    private TouchStatus touchStatus = TouchStatus.STATUS_SINGLE;    // 默认裁剪的宽高    private int cropWidth = 0;    private int cropHeight = 0;    //手指触摸位置    public TouchPosition touchPosition = TouchPosition.EDGE_NONE;    protected Drawable mDrawable;//被裁剪对象    protected FloatDrawable mFloatDrawable;//裁剪层    protected Rect mDrawableSrc = new Rect();// 图片Rect变换时的Rect    protected Rect mDrawableDst = new Rect();// 图片Rect    protected Rect mDrawableFloat = new Rect();// 裁剪层的Rect    private boolean isTouchInSquare = true;//当前触点是否在裁剪框内    protected boolean isFrist = true;//    protected float oriRationWH = 0;//    private boolean isCropEnable = true;    public void setCropEnable(boolean cropEnable) {        this.isCropEnable = cropEnable;    }    /**     * 手指触摸状态     */    public enum TouchStatus {        STATUS_SINGLE,//单指触摸        STATUS_MULTI_START,//多指触摸开始        STATUS_MULTI_TOUCHING,//多指触摸中    }    /**     * 手指触摸位置     */    public enum TouchPosition {        EDGE_LT,//左上角        EDGE_RT,//右上角        EDGE_LB,//左下角        EDGE_RB,//右下角        EDGE_MOVE_IN,//裁剪框内部        EDGE_MOVE_OUT,//裁剪框外部        EDGE_NONE,//nothing    }    public CropImageView(Context context) {        super(context);        init(context);    }    public CropImageView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CropImageView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    /**     * 初始化     *     * @param context     */    private void init(Context context) {        this.mContext = context;        try {            if (android.os.Build.VERSION.SDK_INT >= 11) {                this.setLayerType(LAYER_TYPE_SOFTWARE, null);            }        } catch (Exception e) {            e.printStackTrace();        }        this.isFrist = true;        mFloatDrawable = new FloatDrawable(context);        dimenUtil = new DimenUtil(mContext);        cropWidth = dimenUtil.getScreenWidth();        cropHeight = dimenUtil.getScreenHeight();    }    /**     * 设置被裁剪样本     *     * @param mDrawable     * @param cropWidth     * @param cropHeight     */    public void setDrawable(Drawable mDrawable, int cropWidth, int cropHeight) {        this.cropWidth = cropWidth;        this.cropHeight = cropHeight;        this.mDrawable = mDrawable;        invalidate();    }    /**     * 设置被裁剪样本     *     * @param mDrawable     */    public void setDrawable(Drawable mDrawable) {        this.mDrawable = mDrawable;        invalidate();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        if (event.getPointerCount() > 1) {            switch (touchStatus) {                case STATUS_SINGLE:                    touchStatus = TouchStatus.STATUS_MULTI_START;                    break;                case STATUS_MULTI_START:                    touchStatus = TouchStatus.STATUS_MULTI_TOUCHING;                    break;            }        } else {            switch (touchStatus) {                case STATUS_MULTI_TOUCHING:                case STATUS_MULTI_START:                    mX_1 = event.getX();                    mY_1 = event.getY();                    break;            }            touchStatus = TouchStatus.STATUS_SINGLE;        }        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mX_1 = event.getX();                mY_1 = event.getY();                touchPosition = getTouchPosition(mX_1, mY_1);                isTouchInSquare = mDrawableFloat.contains((int) event.getX(),                        (int) event.getY());                break;            case MotionEvent.ACTION_UP:                checkBounds();                break;            case MotionEvent.ACTION_POINTER_UP:                touchPosition = TouchPosition.EDGE_NONE;                break;            case MotionEvent.ACTION_MOVE:                switch (touchStatus) {                    case STATUS_MULTI_TOUCHING:                        //多指触摸中...                        break;                    case STATUS_SINGLE:                        int dx = (int) (event.getX() - mX_1);                        int dy = (int) (event.getY() - mY_1);                        mX_1 = event.getX();                        mY_1 = event.getY();                        // 根據得到的那一个角,并且变换Rect                        if (!(dx == 0 && dy == 0)) {                            switch (touchPosition) {                                case EDGE_LT:                                    mDrawableFloat.set(mDrawableFloat.left + dx,                                            mDrawableFloat.top + dy, mDrawableFloat.right,                                            mDrawableFloat.bottom);                                    break;                                case EDGE_RT:                                    mDrawableFloat.set(mDrawableFloat.left,                                            mDrawableFloat.top + dy, mDrawableFloat.right                                                    + dx, mDrawableFloat.bottom);                                    break;                                case EDGE_LB:                                    mDrawableFloat.set(mDrawableFloat.left + dx,                                            mDrawableFloat.top, mDrawableFloat.right,                                            mDrawableFloat.bottom + dy);                                    break;                                case EDGE_RB:                                    mDrawableFloat.set(mDrawableFloat.left,                                            mDrawableFloat.top, mDrawableFloat.right + dx,                                            mDrawableFloat.bottom + dy);                                    break;                                case EDGE_MOVE_IN:                                    if (isTouchInSquare) {                                        mDrawableFloat.offset(dx, dy);                                    }                                    break;                                case EDGE_MOVE_OUT:                                    //这部分可以控制图片的缩放,位移                                    break;                            }                            mDrawableFloat.sort();                            invalidate();                        }                        break;                }                break;        }        return true;    }    /**     * 根据初触摸点判断是触摸的Rect哪一个角     */    public TouchPosition getTouchPosition(float eventX, float eventY) {        if (mFloatDrawable.getBounds().left <= eventX                && eventX < (mFloatDrawable.getBounds().left + mFloatDrawable                .getBorderWidth())                && mFloatDrawable.getBounds().top <= eventY                && eventY < (mFloatDrawable.getBounds().top + mFloatDrawable                .getBorderHeight())) {            return TouchPosition.EDGE_LT;        } else if ((mFloatDrawable.getBounds().right - mFloatDrawable                .getBorderWidth()) <= eventX                && eventX < mFloatDrawable.getBounds().right                && mFloatDrawable.getBounds().top <= eventY                && eventY < (mFloatDrawable.getBounds().top + mFloatDrawable                .getBorderHeight())) {            return TouchPosition.EDGE_RT;        } else if (mFloatDrawable.getBounds().left <= eventX                && eventX < (mFloatDrawable.getBounds().left + mFloatDrawable                .getBorderWidth())                && (mFloatDrawable.getBounds().bottom - mFloatDrawable                .getBorderHeight()) <= eventY                && eventY < mFloatDrawable.getBounds().bottom) {            return TouchPosition.EDGE_LB;        } else if ((mFloatDrawable.getBounds().right - mFloatDrawable                .getBorderWidth()) <= eventX                && eventX < mFloatDrawable.getBounds().right                && (mFloatDrawable.getBounds().bottom - mFloatDrawable                .getBorderHeight()) <= eventY                && eventY < mFloatDrawable.getBounds().bottom) {            return TouchPosition.EDGE_RB;        } else if (mFloatDrawable.getBounds().contains((int) eventX, (int) eventY)) {            return TouchPosition.EDGE_MOVE_IN;        }        return TouchPosition.EDGE_MOVE_OUT;    }    @Override    protected void onDraw(Canvas canvas) {        //如果没有设置裁剪样本,则赋值一个空的图层        if (mDrawable == null) {            mDrawable = new BitmapDrawable(mContext.getResources(), getEmptyBitmap());        }        //设定 界限 规则        initBounds();        // 画图片        mDrawable.draw(canvas);        //画裁剪框        drawCropUI(canvas);    }    /**     * 绘制裁剪框样式     *     * @param canvas     */    private void drawCropUI(Canvas canvas) {        if (!isCropEnable) {            return;        }        canvas.save();        // 在画布上画浮层FloatDrawable,Region.Op.DIFFERENCE是表示Rect交集的补集        canvas.clipRect(mDrawableFloat, Region.Op.DIFFERENCE);        // 在交集的补集上画上灰色用来区分        canvas.drawColor(Color.parseColor("#a0000000"));        canvas.restore();        // 画浮层        mFloatDrawable.draw(canvas);    }    /**     * 初始化 界限 参数,在onDraw方法中调用;     * isFirst的目的是下面对mDrawableSrc和mDrawableFloat只初始化一次;     * 之后的变化是根据touch事件来变化的,而不是每次执行重新对mDrawableSrc和mDrawableFloat进行设置     */    protected void initBounds() {        if (isFrist) {            oriRationWH = ((float) mDrawable.getIntrinsicWidth())                    / ((float) mDrawable.getIntrinsicHeight());            final float scale = mContext.getResources().getDisplayMetrics().density;            int w = Math.min(getWidth(), (int) (mDrawable.getIntrinsicWidth()                    * scale + 0.5f));            int h = (int) (w / oriRationWH);            int left = (getWidth() - w) / 2;            int top = (getHeight() - h) / 2;            int right = left + w;            int bottom = top + h;            mDrawableSrc.set(left, top, right, bottom);            mDrawableDst.set(mDrawableSrc);            if (cropWidth > getWidth()) {                cropWidth = getWidth();                cropHeight = cropHeight * cropWidth / cropWidth;            }            if (cropHeight > getHeight()) {                cropHeight = getHeight();                cropWidth = cropWidth * cropHeight / cropHeight;            }            int floatLeft = (getWidth() - cropWidth) / 2;            int floatTop = (getHeight() - cropHeight) / 2;            mDrawableFloat.set(floatLeft, floatTop, floatLeft + cropWidth,                    floatTop + cropHeight);            isFrist = false;        }        mDrawable.setBounds(mDrawableDst);        mFloatDrawable.setBounds(mDrawableFloat);    }    /**     * 在up事件中调用了该方法,目的是检查是否把浮层拖出了屏幕     */    protected void checkBounds() {        int newLeft = mDrawableFloat.left;        int newTop = mDrawableFloat.top;        boolean isChange = false;        if (mDrawableFloat.left < getLeft()) {            newLeft = getLeft();            isChange = true;        }        if (mDrawableFloat.top < getTop()) {            newTop = getTop();            isChange = true;        }        if (mDrawableFloat.right > getRight()) {            newLeft = getRight() - mDrawableFloat.width();            isChange = true;        }        if (mDrawableFloat.bottom > getBottom()) {            newTop = getBottom() - mDrawableFloat.height();            isChange = true;        }        mDrawableFloat.offsetTo(newLeft, newTop);        if (isChange) {            invalidate();        }    }    /**     * 进行图片的裁剪,所谓的裁剪就是根据Drawable的新的坐标在画布上创建一张新的图片     */    public Bitmap getCropImage() {        Bitmap result = null;        if (!isCropEnable) {            return result;        }        Bitmap tmpBitmap = getEmptyBitmap();        Canvas canvas = new Canvas(tmpBitmap);        mDrawable.draw(canvas);        result = Bitmap.createBitmap(tmpBitmap, mDrawableFloat.left,                mDrawableFloat.top, mDrawableFloat.width(),                mDrawableFloat.height());        recycle(tmpBitmap);        return result;    }    private void recycle(Bitmap bitmap) {        try {            if (bitmap != null && !bitmap.isRecycled()) {                bitmap.recycle();                System.gc();            }        } catch (Exception var2) {            var2.printStackTrace();        }    }    private Bitmap getEmptyBitmap() {        return Bitmap.createBitmap(dimenUtil.getScreenWidth(), dimenUtil.getScreenHeight(), Bitmap.Config.RGB_565);    }}


以上,类中用到的工具类:

import android.content.Context;import android.view.View;/** * Created by hmy  */public class DimenUtil {    private Context mContext;    private float density = -1.0F;    private int widthPixels = -1;    private int heightPixels = -1;    public DimenUtil(Context context) {        this.mContext = context;    }    public float getDensity() {        if (density <= 0.0F) {            density = mContext.getResources().getDisplayMetrics().density;        }        return density;    }    public int dip2px(float dpValue) {        return (int) (dpValue * getDensity() + 0.5F);    }    public int px2dip(float pxValue) {        return (int) (pxValue / getDensity() + 0.5F);    }    public int getScreenWidth() {        if (widthPixels <= 0) {            widthPixels = mContext.getResources().getDisplayMetrics().widthPixels;        }        return widthPixels;    }    public int getScreenHeight() {        if (heightPixels <= 0) {            heightPixels = mContext.getResources().getDisplayMetrics().heightPixels;        }        return heightPixels;    }}
还需要把裁剪框封装到另一个控件中,使用的时候将下面的控件作为根布局,调用相关方法就可以截屏其包含的view:

import android.content.Context;import android.graphics.Bitmap;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.view.View;import android.view.ViewTreeObserver;import android.widget.FrameLayout;/** * Created by hmy  */public class ScreenShotView extends FrameLayout {    private Context mContext;    private CropImageView mCropIv;    private int mWidth = 0;    private int mHeight = 0;    public ScreenShotView(Context context) {        super(context);        init(context);    }    public ScreenShotView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public ScreenShotView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        this.mContext = context;        mCropIv = new CropImageView(mContext);    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        checkChildView();    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);        this.mWidth = this.getWidth();        this.mHeight = this.getHeight();    }    /**     * 检查子view     */    private void checkChildView() {        int count = this.getChildCount();        if (count != 1) {            throw new RuntimeException("ScreenShotView can only have one child view!");        } else {            this.addView(mCropIv);            initScreenView();        }    }    /**     * 初始化截屏view     */    private void initScreenView() {        final View screenView = this.getChildAt(0);        screenView.buildDrawingCache();        // 允许当前窗口保存缓存信息        screenView.setDrawingCacheEnabled(true);        //view加载完成时回调        screenView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            @Override            public void onGlobalLayout() {                try {                    //获取bitmap                    Bitmap bmp = Bitmap.createBitmap(screenView.getDrawingCache(), 0, 0, mWidth, mHeight);                    // 销毁缓存信息                    screenView.destroyDrawingCache();                    mCropIv.setDrawable(new BitmapDrawable(mContext.getResources(), bmp));                } catch (Exception e) {                    e.printStackTrace();                }            }        });    }    /**     * 获取截取框内的图片     *     * @return     */    public Bitmap getCropImage() {        return mCropIv.getCropImage();    }    public void setCropEnable(boolean enable) {        mCropIv.setCropEnable(enable);    }}
使用方法:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.hmy.android.allforme.view.ScreenShotView        android:id="@+id/main_crop"        android:layout_width="match_parent"        android:layout_height="match_parent">        <ImageView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:src="@mipmap/bj" />    </com.hmy.android.allforme.view.ScreenShotView>    <ImageView        android:id="@+id/main_iv"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_alignParentRight="true"        android:background="#afff"        android:src="@mipmap/groundoverlay" /></RelativeLayout>

import android.app.Activity;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.widget.ImageView;import com.hmy.android.allforme.R;import com.hmy.android.allforme.view.ScreenShotView;public class MainActivity extends Activity {    private ScreenShotView imageView;    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        imageView = (ScreenShotView) findViewById(R.id.main_crop);        iv = (ImageView) findViewById(R.id.main_iv);        iv.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Bitmap mBitmap = imageView.getCropImage();                iv.setImageBitmap(mBitmap);            }        });    }}

0 0