zoukankan      html  css  js  c++  java
  • Android 自定义截图,可设置裁剪框宽高

    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~~~~~~~~~~~~

    本文来自博客园,作者:Forever丶随风,转载请注明原文链接:https://www.cnblogs.com/Forever-wind/p/14955478.html

  • 相关阅读:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    php使用 _before_index() 来实现访问页面前,判断登录
    php使用 _before_index() 来实现访问页面前,判断登录
    查询方式实例演示
    查询方式实例演示
    haproxy timeout server 46000 后台超时时间
    haproxy timeout server 46000 后台超时时间
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
  • 原文地址:https://www.cnblogs.com/Forever-wind/p/14955478.html
Copyright © 2011-2022 走看看