码迷,mamicode.com
首页 > 移动开发 > 详细

Android 自定义截图,可设置裁剪框宽高

时间:2021-07-01 16:20:29      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:touch事件   extern   mis   xml文件   ppc   输入   hang   attr   其他应用   

1.创建一个Android Demo项目,设置拍照,读取等权限(基本的就不讲了,主要说明重点。)

2.创建自定义View 

public class CropImageView extends View {
    // 在touch重要用到的点,
    private float mX_1 = 0;
    private float mY_1 = 0;
    // 触摸事件判断
    private final int STATUS_SINGLE = 1;
    private final int STATUS_MULTI_START = 2;
    private final int STATUS_MULTI_TOUCHING = 3;
    // 当前状态
    private int mStatus = STATUS_SINGLE;
    // 默认裁剪的宽高
    private int cropWidth;
    private int cropHeight;
    // 浮层Drawable的四个点
    private final int EDGE_LT = 1;
    private final int EDGE_RT = 2;
    private final int EDGE_LB = 3;
    private final int EDGE_RB = 4;
    private final int EDGE_MOVE_IN = 5;
    private final int EDGE_MOVE_OUT = 6;
    private final int EDGE_NONE = 7;

    public int currentEdge = EDGE_NONE;

    protected float oriRationWH = 0;
    protected final float maxZoomOut = 5.0f;
    protected final float minZoomIn = 0.333333f;

    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
    protected boolean isFrist = true;
    private boolean isTouchInSquare = true;

    protected Context mContext;

    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);

    }

    @SuppressLint("NewApi")
    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();
        }
        mFloatDrawable = new FloatDrawable(context);
    }

    public void setDrawable(Drawable mDrawable, int cropWidth, int cropHeight) {
        this.mDrawable = mDrawable;
        this.cropWidth = cropWidth;
        this.cropHeight = cropHeight;
        this.isFrist = true;
        invalidate();
    }

      @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getPointerCount() > 1) {
            if (mStatus == STATUS_SINGLE) {
                mStatus = STATUS_MULTI_START;
            } else if (mStatus == STATUS_MULTI_START) {
                mStatus = STATUS_MULTI_TOUCHING;
            }
        } else {
            if (mStatus == STATUS_MULTI_START
                    || mStatus == STATUS_MULTI_TOUCHING) {
                mX_1 = event.getX();
                mY_1 = event.getY();
            }

            mStatus = STATUS_SINGLE;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mX_1 = event.getX();
                mY_1 = event.getY();
                currentEdge = getTouch((int) mX_1, (int) mY_1);
                isTouchInSquare = mDrawableFloat.contains((int) event.getX(),
                        (int) event.getY());

                break;

            case MotionEvent.ACTION_UP:
                checkBounds();
                break;

            case MotionEvent.ACTION_POINTER_UP:
                currentEdge = EDGE_NONE;
                break;

            case MotionEvent.ACTION_MOVE:
                if (mStatus == STATUS_MULTI_TOUCHING) {

                } else if (mStatus == 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 (currentEdge) {
                            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((int) dx, (int) dy);
                                }
                                break;

                            case EDGE_MOVE_OUT:
                                break;
                        }
                        mDrawableFloat.sort();
                        invalidate();
                    }
                }
                break;
        }

        return true;
    }

    // 根据初触摸点判断是触摸的Rect哪一个角
    public int getTouch(int eventX, int eventY) {
        if (mFloatDrawable.getBounds().left <= eventX
                && eventX < (mFloatDrawable.getBounds().left + mFloatDrawable
                .getBorderWidth())
                && mFloatDrawable.getBounds().top <= eventY
                && eventY < (mFloatDrawable.getBounds().top + mFloatDrawable
                .getBorderHeight())) {
            return 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 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 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 EDGE_RB;
        } else if (mFloatDrawable.getBounds().contains(eventX, eventY)) {
            return EDGE_MOVE_IN;
        }
        return EDGE_MOVE_OUT;
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (mDrawable == null) {
            return;
        }

        if (mDrawable.getIntrinsicWidth() == 0
                || mDrawable.getIntrinsicHeight() == 0) {
            return;
        }

        configureBounds();
        // 在画布上花图片
        mDrawable.draw(canvas);
        canvas.save();
        // 在画布上画浮层FloatDrawable,Region.Op.DIFFERENCE是表示Rect交集的补集
        canvas.clipRect(mDrawableFloat, Region.Op.DIFFERENCE);
        // 在交集的补集上画上灰色用来区分
        canvas.drawColor(Color.parseColor("#a0000000"));
        canvas.restore();
        // 画浮层
        mFloatDrawable.draw(canvas);
    }

    protected void configureBounds() {
        // configureBounds在onDraw方法中调用
        // isFirst的目的是下面对mDrawableSrc和mDrawableFloat只初始化一次,
        // 之后的变化是根据touch事件来变化的,而不是每次执行重新对mDrawableSrc和mDrawableFloat进行设置
        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);

            int floatWidth = dipTopx(mContext, cropWidth);
            int floatHeight = dipTopx(mContext, cropHeight);

            if (floatWidth > getWidth()) {
                floatWidth = getWidth();
                floatHeight = cropHeight * floatWidth / cropWidth;
            }

            if (floatHeight > getHeight()) {
                floatHeight = getHeight();
                floatWidth = cropWidth * floatHeight / cropHeight;
            }

            int floatLeft = (getWidth() - floatWidth) / 2;
            int floatTop = (getHeight() - floatHeight) / 2;
            mDrawableFloat.set(floatLeft, floatTop, floatLeft + floatWidth,
                    floatTop + floatHeight);

            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 tmpBitmap = Bitmap.createBitmap(getWidth(), getHeight(),
                Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(tmpBitmap);
        mDrawable.draw(canvas);

        Matrix matrix = new Matrix();
        float scale = (float) (mDrawableSrc.width())
                / (float) (mDrawableDst.width());
        matrix.postScale(scale, scale);

        Bitmap ret = Bitmap.createBitmap(tmpBitmap, mDrawableFloat.left,
                mDrawableFloat.top, mDrawableFloat.width(),
                mDrawableFloat.height(), matrix, true);
        tmpBitmap.recycle();
        tmpBitmap = null;

        return ret;
    }

    public int dipTopx(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

}

3. 创建XML文件,效果如图(样式不是很好看,主要实现功能就行)

技术图片

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="5dp"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="宽度:" />

        <EditText
            android:id="@+id/width"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="5dp"
            android:inputType="number"
            android:singleLine="true" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="高度:" />

        <EditText
            android:id="@+id/height"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="5dp"
            android:inputType="number"
            android:singleLine="true" />

        <Button
            android:id="@+id/sure"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="5dp"
            android:text="确定" />

        <Button
            android:id="@+id/crop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:text="裁剪" />


        <Button
            android:id="@+id/save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="5dp"

            android:text="保存" />

        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="取消" />


    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">

        <com.example.cropphoto.util.CropImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ImageView
            android:id="@+id/image2"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </RelativeLayout>


</LinearLayout>

 

4.创建裁剪框

public class FloatDrawable extends Drawable {
    private Context mContext;
    private int offset = 50;
    private Paint mLinePaint = new Paint();
    private Paint mLinePaint2 = new Paint();
    {
        mLinePaint.setARGB(200, 50, 50, 50);
        mLinePaint.setStrokeWidth(1F);
        mLinePaint.setStyle(Paint.Style.STROKE);
        mLinePaint.setAntiAlias(true);
        mLinePaint.setColor(Color.WHITE);
        //
        mLinePaint2.setARGB(200, 50, 50, 50);
        mLinePaint2.setStrokeWidth(7F);
        mLinePaint2.setStyle(Paint.Style.STROKE);
        mLinePaint2.setAntiAlias(true);
        mLinePaint2.setColor(Color.WHITE);
    }

    public FloatDrawable(Context context) {
        super();
        this.mContext = context;

    }

    public int getBorderWidth() {
        return dipTopx(mContext, offset);//根据dip计算的像素值,做适配用的
    }

    public int getBorderHeight() {
        return dipTopx(mContext, offset);
    }

    @Override
    public void draw(Canvas canvas) {

        int left = getBounds().left;
        int top = getBounds().top;
        int right = getBounds().right;
        int bottom = getBounds().bottom;

        Rect mRect = new Rect(left + dipTopx(mContext, offset) / 2, top
                + dipTopx(mContext, offset) / 2, right
                - dipTopx(mContext, offset) / 2, bottom
                - dipTopx(mContext, offset) / 2);
        //画默认的选择框
        canvas.drawRect(mRect, mLinePaint);
        //画四个角的四个粗拐角、也就是八条粗线
        canvas.drawLine((left + dipTopx(mContext, offset) / 2 - 3.5f), top
                        + dipTopx(mContext, offset) / 2,
                left + dipTopx(mContext, offset) - 8f,
                top + dipTopx(mContext, offset) / 2, mLinePaint2);
        canvas.drawLine(left + dipTopx(mContext, offset) / 2,
                top + dipTopx(mContext, offset) / 2,
                left + dipTopx(mContext, offset) / 2,
                top + dipTopx(mContext, offset) / 2 + 30, mLinePaint2);
        canvas.drawLine(right - dipTopx(mContext, offset) + 8f,
                top + dipTopx(mContext, offset) / 2,
                right - dipTopx(mContext, offset) / 2,
                top + dipTopx(mContext, offset) / 2, mLinePaint2);
        canvas.drawLine(right - dipTopx(mContext, offset) / 2,
                top + dipTopx(mContext, offset) / 2 - 3.5f,
                right - dipTopx(mContext, offset) / 2,
                top + dipTopx(mContext, offset) / 2 + 30, mLinePaint2);
        canvas.drawLine((left + dipTopx(mContext, offset) / 2 - 3.5f), bottom
                        - dipTopx(mContext, offset) / 2,
                left + dipTopx(mContext, offset) - 8f,
                bottom - dipTopx(mContext, offset) / 2, mLinePaint2);
        canvas.drawLine((left + dipTopx(mContext, offset) / 2), bottom
                        - dipTopx(mContext, offset) / 2,
                (left + dipTopx(mContext, offset) / 2),
                bottom - dipTopx(mContext, offset) / 2 - 30f, mLinePaint2);
        canvas.drawLine((right - dipTopx(mContext, offset) + 8f), bottom
                        - dipTopx(mContext, offset) / 2,
                right - dipTopx(mContext, offset) / 2,
                bottom - dipTopx(mContext, offset) / 2, mLinePaint2);
        canvas.drawLine((right - dipTopx(mContext, offset) / 2), bottom
                        - dipTopx(mContext, offset) / 2 - 30f,
                right - dipTopx(mContext, offset) / 2,
                bottom - dipTopx(mContext, offset) / 2 + 3.5f, mLinePaint2);

    }

    @Override
    public void setBounds(Rect bounds) {
        super.setBounds(new Rect(bounds.left - dipTopx(mContext, offset) / 2,
                bounds.top - dipTopx(mContext, offset) / 2, bounds.right
                + dipTopx(mContext, offset) / 2, bounds.bottom
                + dipTopx(mContext, offset) / 2));
    }

    @Override
    public void setAlpha(int alpha) {

    }

    @Override
    public void setColorFilter(ColorFilter cf) {

    }

    @SuppressLint("WrongConstant")
    @Override
    public int getOpacity() {
        return 0;
    }

    public int dipTopx(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

 

5.创建Activity和Image工具类

 

public class ResizePhotoActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText width;
    private EditText height;
    private Button sure, cancel, crop,save;
    private CropImageView imageView;

    private ImageUtils imageUtils;
    private ImageView image2;

    private Bitmap bitmap;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_resizephoto);

        imageView = findViewById(R.id.image);
        image2 = findViewById(R.id.image2);

        width = findViewById(R.id.width);
        height = findViewById(R.id.height);
        sure = findViewById(R.id.sure);
        sure.setOnClickListener(this);

        cancel = findViewById(R.id.btn_cancel);
        cancel.setOnClickListener(this);

        crop = findViewById(R.id.crop);
        crop.setOnClickListener(this);

        save = findViewById(R.id.save);
        save.setOnClickListener(this);

//        bitmap = BitmapFactory.decodeFile(ImageUtils.imgPathOri);
//        imageView.setDrawable(ImageUtils.imgPathOri);

        new Thread(new Runnable() {
            Drawable drawable = loadImage(ImageUtils.imgPathOri);

            @Override
            public void run() {
                imageView.post(new Runnable() {
                    @Override
                    public void run() {
                        imageView.setDrawable(drawable, 200, 200);
                    }
                });

            }
        }).start();

    }

    /**
     * 路径文件转资源文件
     *
     * @param path
     * @return
     */
    public Drawable loadImage(String path) {
        Drawable drawable = null;

        Bitmap bm = BitmapFactory.decodeFile(path);
        drawable = new BitmapDrawable(bm);

        if (drawable == null) {
            Log.d("test", "null drawable");
        } else {
            Log.d("test", "not null drawable");
        }
        return drawable;
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.sure:
                if (width.getText().toString().equals("") && height.getText().toString().equals("")) {
                    Toast.makeText(ResizePhotoActivity.this, "请输入裁剪宽高", Toast.LENGTH_SHORT).show();
                } else {
                    final int w = Integer.valueOf(width.getText().toString());
                    final int h = Integer.valueOf(height.getText().toString());

//                    Bitmap croppedImage = imageView.getCropImage();
                    new Thread(new Runnable() {
                        Drawable drawable = new BitmapDrawable(ImageUtils.imgPathOri);

                        @Override
                        public void run() {
                            imageView.post(new Runnable() {
                                @Override
                                public void run() {
                                    imageView.setDrawable(drawable, w, h);
                                }
                            });

                        }
                    }).start();
                }
                break;

            case R.id.btn_cancel:
                new Thread(new Runnable() {
                    Drawable drawable = loadImage(ImageUtils.imgPathOri);

                    @Override
                    public void run() {
                        imageView.post(new Runnable() {
                            @Override
                            public void run() {
                                imageView.setDrawable(drawable, 200, 200);
                                image2.setImageBitmap(null);
                            }
                        });

                    }
                }).start();
                break;

            case R.id.crop:

                final Bitmap croppedImage = imageView.getCropImage();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        imageView.post(new Runnable() {
                            @Override
                            public void run() {
                                image2.setImageBitmap(croppedImage);
                            }
                        });

                    }
                }).start();
                break;

            case R.id.save:
                ImageUtils imageUtils=new ImageUtils(ResizePhotoActivity.this);
                try {
                    imageUtils.createCropImageFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Bitmap bitmap = imageView.getCropImage();
                System.out.println("---"+ImageUtils.imgPathCrop);

                try {
                    FileOutputStream fos = new FileOutputStream(ImageUtils.imgPathCrop);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    fos.flush();
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                this.finish();

        }
    }


}

 

 

public class ImageUtils {
    //原图像 路径
    public static String imgPathOri;
    //裁剪图像 路径
    public static String imgPathCrop;
    //原图像 URI
    public Uri imgUriOri;
    //裁剪图像 URI
    public Uri imgUriCrop;
    public PopupWindow popWinChoose;
    public static final String TAG = "ImageUtils";
    public static final int REQUEST_OPEN_CAMERA = 0x011;
    public static final int REQUEST_OPEN_GALLERY = 0x022;
    public static final int REQUEST_CROP_PHOTO = 0x033;
    public static final int REQUEST_PERMISSIONS = 0x044;
    Activity activity;

    public ImageUtils(Activity activity) {
        this.activity = activity;
    }

    /**
     * ImageView设置优化内存使用后的Bitmap
     * 返回一个等同于ImageView宽高的bitmap
     *
     * @param view    ImageView
     * @param imgPath 图像路径
     */
    public static void imageViewSetPic(ImageView view, String imgPath) {
        // Get the dimensions of the View
        int targetW = view.getWidth();
        int targetH = view.getHeight();

        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        Bitmap bitmap = BitmapFactory.decodeFile(imgPath, bmOptions);
        view.setImageBitmap(bitmap);
    }

    /**
     * 创建原图像保存的文件
     *
     * @return
     * @throws IOException
     */
    public File createOriImageFile() throws IOException {
        String imgNameOri = "HomePic_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File pictureDirOri = new File(activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/OriPicture");
        if (!pictureDirOri.exists()) {
            pictureDirOri.mkdirs();
        }
        File image = File.createTempFile(
                imgNameOri,         /* prefix */
                ".jpg",             /* suffix */
                pictureDirOri       /* directory */
        );
        imgPathOri = image.getAbsolutePath();
        return image;
    }

    /**
     * 创建裁剪图像保存的文件
     *
     * @return
     * @throws IOException
     */
    public File createCropImageFile() throws IOException {
        String imgNameCrop = "HomePic_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File pictureDirCrop = new File(activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/CropPicture");
        if (!pictureDirCrop.exists()) {
            pictureDirCrop.mkdirs();
        }
        File image = File.createTempFile(
                imgNameCrop,         /* prefix */
                ".jpg",             /* suffix */
                pictureDirCrop      /* directory */
        );
        imgPathCrop = image.getAbsolutePath();
        return image;
    }

    /**
     * 把图像添加进系统相册
     *
     * @param imgPath 图像路径
     */
    public void addPicToGallery(String imgPath) {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File(imgPath);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        activity.sendBroadcast(mediaScanIntent);
    }

    public void setWindowAlpha(float alpha) {
        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.alpha = alpha;
        activity.getWindow().setAttributes(lp);
    }

    /**
     * 打开相机
     * 7.0中如果需要调用系统(eg:裁剪)/其他应用,必须用FileProvider提供Content Uri,并且将Uri赋予读写的权限
     */
    public void openCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 打开相机
        File oriPhotoFile = null;
        try {
            oriPhotoFile = createOriImageFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (oriPhotoFile != null) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                imgUriOri = Uri.fromFile(oriPhotoFile);
            } else {
                imgUriOri = FileProvider.getUriForFile(this.activity, activity.getPackageName(), oriPhotoFile);
            }
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUriOri);
            activity.startActivityForResult(intent, REQUEST_OPEN_CAMERA);

            // 动态grant权限
            // 如果在xml中已经定义android:grantUriPermissions="true"
            // 则只需要intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);即可
            //            List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
            //            for (ResolveInfo resolveInfo : resInfoList) {
            //                String packageName = resolveInfo.activityInfo.packageName;
            //                grantUriPermission(packageName, imgUriOri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            //            }
        }
    }


    public void openGallery() {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
        } else {
            intent.setAction(Intent.ACTION_GET_CONTENT);
//            intent.setAction(Intent.ACTION_PICK);
        }
        intent.setType("image/*");
        activity.startActivityForResult(intent, REQUEST_OPEN_GALLERY);
    }


    /**
     * 裁剪图片
     *
     * @param uri 需要 裁剪图像的Uri
     */
    public void cropPhoto(Uri uri) {

        Intent intent = new Intent("com.android.camera.action.CROP");
        File cropPhotoFile = null;
        try {
            cropPhotoFile = createCropImageFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (cropPhotoFile != null) {
//            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
//                imgUriCrop = Uri.fromFile(cropPhotoFile);
//            }else{
//                imgUriCrop = FileProvider.getUriForFile(this.activity,activity.getPackageName(), cropPhotoFile);
//            }

            //7.0 安全机制下不允许保存裁剪后的图片
            //所以仅仅将File Uri传入MediaStore.EXTRA_OUTPUT来保存裁剪后的图像
            imgUriCrop = Uri.fromFile(cropPhotoFile);

            intent.setDataAndType(uri, "image/*");
            intent.putExtra("crop", true);
//            intent.putExtra("aspectX", 100);
//            intent.putExtra("aspectY", 100);
//            intent.putExtra("outputX", w);
//            intent.putExtra("outputY", h);
            intent.putExtra("return-data", false);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUriCrop);
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            activity.startActivityForResult(intent, REQUEST_CROP_PHOTO);

        }
    }


    public void initChoosePop() {
        View view = LayoutInflater.from(activity).inflate(R.layout.popwin_sel, null);
        popWinChoose = new PopupWindow(view, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
        popWinChoose.setFocusable(true); // 设置popWindow弹出窗体可点击
        popWinChoose.setBackgroundDrawable(new ColorDrawable(activity.getResources().getColor(R.color.transparent)));
//        popWinChoose.setAnimationStyle(R.style.storeImageChooseStyle);
        popWinChoose.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                setWindowAlpha(1); //Window设置为全透明
            }
        });
        TextView btnFirst = (TextView) view.findViewById(R.id.btn_first);
        TextView btnSecond = (TextView) view.findViewById(R.id.btn_second);
        TextView btnThird =(TextView) view.findViewById(R.id.btn_third);
        btnFirst.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                openCamera();
                popWinChoose.dismiss();
            }

        });
        btnSecond.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openGallery();
                popWinChoose.dismiss();
            }

        });
        btnThird.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popWinChoose.dismiss();
            }

        });

    }




}

 

流程:首先需要调用系统相机拍照,在OnActivityResult方法返回值时,跳转到自定义裁剪Activity,点击保存后回退主界面,调用OnResume方法获取裁剪后的url路径,加载显示即可。

效果如下图:

 

 

技术图片

 

 

 

技术图片

 

 

 

~~~~~~~~~~~~Over~~~~~~~~~~~~

 

Android 自定义截图,可设置裁剪框宽高

标签:touch事件   extern   mis   xml文件   ppc   输入   hang   attr   其他应用   

原文地址:https://www.cnblogs.com/Forever-wind/p/14955478.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!