zoukankan      html  css  js  c++  java
  • 图片选择器ImageEditContainer

    1. 简介

    本次demo中一共封装了两个组件:ImageEditButton 和 ImageEditContainer。其中ImageEditContainer 是在 ImageEditButton,两个组件可单独使用。

    在demo中,实现了 图片选择(拍照+本地),裁剪,压缩,保存本地 以及对已选择图片的删除操作(如果有修改需求,也可以使用对应方法进行操作,该方法已添加);

     还有就是 针对 6.0权限的处理问题,本次使用了第三方库 rxpermissions 进行权限的处理。

    2.项目主目录结构

    3. 功能介绍

    MainActivity.java 界面效果图:

     

     

    ImageEditContainer 组件初始化:
            layImageContainer = (ImageEditContainer) findViewById(R.id.lay_image_container);
            layImageContainer.setEditListener(this);
            layImageContainer.setBtnImageResource(R.drawable.icon_picture_photograph);
            layImageContainer.setTotalImageQuantity(3);

    如上代码,设置组件的监听,添加按钮展示图,以及最多选择图片个数。

    implements  ImageEditContainer.ImageEditContainerListener 的实现
    @Override
        public void doAddImage() {
            PopupWindow mCameraPop = SelectPicturePopupWindowUtils.showSelectPicturePopupWindow(this);
            if (mCameraPop != null)
                mCameraPop.showAtLocation(layImageContainer, Gravity.BOTTOM, 0, 0);
        }
    
        @Override
        public void doEditLocalImage(ImageItem imageItem) {
            if (imageItem != null) {
                layImageContainer.updateEditedImageItem(imageItem);
            }
        }
    
        @Override
        public void doEditRemoteImage(RemoteImageItem remoteImageItem) {
            if (remoteImageItem != null) {
                if (remoteImageItem.isDeleted) {
                    layImageContainer.removeRemoteImageItem(remoteImageItem);
                } else {
                    layImageContainer.updateRemoteImageItem(remoteImageItem);
                }
            }
        }
    

      

    当图片选择数量达到最大个数时,添加按钮会消失。效果图如下所示:

    图片裁剪 效果图如下所示:

    图片可拖拽,缩放


    图片选择好后,进行图片压缩:
        private void compressImage(String path) {
    
            if (TextUtils.isEmpty(path)) {
                return;
            }
            compressImage = compressImage + 1;
            ImageItem imageItem = new ImageItem();
            imageItem.storedPath = path;
    
            File file = new File(FilePathUtils.getImageSavePath());
            if (!file.exists()) {
                file.mkdirs();
            }
            String filePath = FilePathUtils.getImageSavePath() + System.currentTimeMillis() + ".jpg";
            new Thread(new MyThread(imageItem, path, filePath)).start();
            List<String> imagePaths = new ArrayList<>();
            imagePaths.add(path);
            layImageContainer.addNewImageItem(imageItem);
        }

    图片压缩比较慢,要开启个 线程进行压缩:

    public class MyThread implements Runnable {
            private String imgPath;
            private String outPath;
            private ImageItem imageItem;
    
            public MyThread(ImageItem imageItem, String imgPath, String outPath) {
                this.imageItem = imageItem;
                this.imgPath = imgPath;
                this.outPath = outPath;
            }
    
            public void run() {
                try {
                    BitmapUtil.compressAndGenImage(imgPath, outPath, 500, false);
                    compressImage = compressImage - 1;
                    imageItem.storedPath = outPath;
                } catch (IOException e) {
                    compressImage = compressImage - 1;
                    e.printStackTrace();
                }
            }
        }

    使用的压缩方法:

        /**
         * Compress by quality,  and generate image to the path specified
         *
         * @param imgPath
         * @param outPath
         * @param maxSize     target will be compressed to be smaller than this size.(kb)
         * @param needsDelete Whether delete original file after compress
         * @throws IOException
         */
        public static void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {
            compressAndGenImage(getBitmap(imgPath), outPath, maxSize);
    
            // Delete original file
            if (needsDelete) {
                File file = new File(imgPath);
                if (file.exists()) {
                    file.delete();
                }
            }
        }

    组件 ImageEditContainer 添加图片方法介绍:

    可添加本地和网络图片

        /**
         * 添加本地图片 
         * List<String> storePaths 本地图片路径数组
         */
        public void addNewImages(List<String> storePaths) {
    
    
        }
    
    
        /**
         * 添加本地图片
         */
        public void addNewImageItem(ImageItem imageItem) {
    
        }
    
        /**
         * 添加网络图片
         */
        public void addRemoteImageItem(RemoteImageItem remoteImageItem) {
    
        }

    组件 ImageEditContainer 其他方法介绍:

       /**
         * 设置组件中 选择按钮的宽高
         */
    public void setImvHeightAndWidth(int height, int width) {
    
        }
      /**
         * 设置图片最大数量
         */
        public void setTotalImageQuantity(int totalImageQuantity) {
    
        }
    /**
         * 设置图片展示图
         */
        public void setBtnImageResource(int resid) {
    
        }
      /**
         * 获取组件中所有图片对象(本地+网络)
         */
        public List<Object> getAllImageItems() {
    
        }
    
      public void updateEditedImageItem(ImageItem imageItem) {
          
        }
    
      /**
         * 更新网络图片
         */
        public void updateRemoteImageItem(RemoteImageItem remoteImageItem) {
    }
    
      /**
         * 删除网络图片
         */
        public void removeRemoteImageItem(RemoteImageItem remoteImageItem) {
    }

    4. 组件代码

    1.ImageEditButton.java 

    /**
     * Created by dingzuoqiang on 2017/6/20.
     * Email: 530858106@qq.com
     */
    public class ImageEditButton extends RelativeLayout {
    
        private final static String TAG = "ImageEditButton";
    
        private ImageView imvAddImage;
        private ImageView imvEdit;
    
        private int imvHeight;
        private int imvWidth;
        public ImageEditButtonListener editButtonListener;
    
        public ImageEditButton(Context context) {
            this(context, null);
        }
    
    
        public ImageEditButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            LayoutInflater.from(context).inflate(R.layout.image_edit_button_view, this, true);
            imvHeight = CommonUtil.dip2px(getContext(), 70);
            imvWidth = imvHeight;
            imvAddImage = (ImageView) findViewById(R.id.imv_add_image);
            imvEdit = (ImageView) findViewById(R.id.imv_edit);
            setImvHeightAndWidth(imvHeight, imvWidth);
            imvAddImage.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    doEditImage();
                }
            });
            imvEdit.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    doEditImage2();
                }
            });
        }
    
        public void setImvHeightAndWidth(int height, int width) {
            this.imvHeight = height;
            this.imvWidth = width;
            ViewGroup.LayoutParams layoutParams = imvAddImage.getLayoutParams();
            layoutParams.width = imvHeight;
            layoutParams.height = imvWidth;
            imvAddImage.setLayoutParams(layoutParams);
        }
    
        public int getImvHeight() {
            return imvHeight;
        }
    
        public int getImvWidth() {
            return imvWidth;
        }
    
        public void setPadding2(int left, int top, int right, int bottom) {
            this.setPadding(left, top, right, bottom);
        }
    
        public void setBtnImageResource(int resid) {
            imvAddImage.setImageResource(resid);
    //        ImageLoaderUtils.loadImageFromDrawable(resid, imvAddImage, null);
        }
    
        public void reset() {
            imvEdit.setVisibility(GONE);
        }
    
        public void setEditButtonListener(ImageEditButtonListener editButtonListener) {
            this.editButtonListener = editButtonListener;
        }
    
        public BaseImageItem getImageItem() {
            Object object = this.getTag();
            if (object instanceof BaseImageItem) return (BaseImageItem) object;
            return null;
        }
    
        public void displayUI() {
            //
            Object object = this.getTag();
            if (object == null) return;
            if (object instanceof ImageItem) {
                ImageItem imageItem = (ImageItem) object;
    
                if (TextUtils.isEmpty(imageItem.storedPath))
                    return;
                File file = new File(imageItem.storedPath);
                if (file.exists()) {
    //                其实Glide加载本地图片和加载网络图片调用的方法是一样的,唯一的区别是说加载SD卡的图片需要SD卡的权限,加载网络需要网络权限
                    Glide.with(getContext()).load(file).crossFade().into(imvAddImage);
                }
            } else if (object instanceof RemoteImageItem) {
                // 如果是 remoteImageItem 则需要从读取图片,同时不可以裁剪
                RemoteImageItem remoteImageItem = (RemoteImageItem) object;
                Glide.with(getContext()).load(remoteImageItem.thumbUrl).centerCrop().crossFade().into(imvAddImage);
            }
    
            // TODO
            BaseImageItem baseImageItem = (BaseImageItem) object;
            displayNoteIcons(baseImageItem);
        }
    
        private void displayNoteIcons(BaseImageItem baseImageItem) {
            imvEdit.setVisibility(VISIBLE);
        }
    
        private void doEditImage() {
            if (editButtonListener == null) return;
    
            Object object = this.getTag();
            if (object == null) {
                // add image
                editButtonListener.doAddImage();
            } else {
                //
                if (object instanceof ImageItem) {
                    editButtonListener.doEditLocalImage((ImageItem) object);
                } else if (object instanceof RemoteImageItem) {
                    editButtonListener.doEditRemoteImage((RemoteImageItem) object);
                }
            }
    
    
        }
    
        private void doEditImage2() {
            if (editButtonListener == null) return;
    
            Object object = this.getTag();
            if (object != null) {
                //
                if (object instanceof ImageItem) {
                    ImageItem imageItem = (ImageItem) object;
                    imageItem.isDeleted = true;
                    editButtonListener.doEditLocalImage(imageItem);
                } else if (object instanceof RemoteImageItem) {
                    RemoteImageItem remoteImageItem = (RemoteImageItem) object;
                    remoteImageItem.isDeleted = true;
                    editButtonListener.doEditRemoteImage(remoteImageItem);
                }
            }
    
    
        }
    
    
        public interface ImageEditButtonListener {
    
            public void doAddImage();
    
            public void doEditLocalImage(ImageItem imageItem1);
    
            public void doEditRemoteImage(RemoteImageItem remoteImageItem);
        }
    
    
    }

    2.ImageEditContainer.java 

    /**
     * Created by dingzuoqiang on 2017/6/20.
     * Email: 530858106@qq.com
     */
    public class ImageEditContainer extends HorizontalScrollView implements ImageEditButton.ImageEditButtonListener {
    
        private final static String TAG = "ImageEditContainer";
        public ImageEditContainerListener mEditListener;
        private int idValue = 0;
        ImageEditButton imbAddImage;
        ViewGroup buttonsContainer;
    
        private int totalImageQuantity = 3;// 总添加数量
        private int mBtnBgResid = 0;
    
        public ImageEditContainer(Context context) {
            //super(context);
            this(context, null);
        }
    
        public ImageEditContainer(Context context, AttributeSet attrs) {
            super(context, attrs);
            //
            LayoutInflater.from(context).inflate(R.layout.image_edit_container, this, true);
    
            imbAddImage = (ImageEditButton) findViewById(R.id.imb_add_image);
            imbAddImage.setEditButtonListener(this);
            //
            buttonsContainer = (ViewGroup) findViewById(R.id.lay_container);
            setHorizontalScrollBarEnabled(false);
            setHorizontalFadingEdgeEnabled(false);
    
        }
    
        public void setImvHeightAndWidth(int height, int width) {
            for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
                ImageEditButton imageEditButton = (ImageEditButton) buttonsContainer.getChildAt(i);
                if (imageEditButton == null) continue;
                imageEditButton.setImvHeightAndWidth(height, width);
            }
        }
    
        public void setTotalImageQuantity(int totalImageQuantity) {
            if (totalImageQuantity > 0)
                this.totalImageQuantity = totalImageQuantity;
        }
    
        public void setBtnImageResource(int resid) {
            mBtnBgResid = resid;
            imbAddImage.setBtnImageResource(mBtnBgResid);
        }
    
        public List<Object> getAllImageItems() {
            List<Object> allItems = new ArrayList<>();
            for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
                ImageEditButton imageEditButton = (ImageEditButton) buttonsContainer.getChildAt(i);
                if (imageEditButton == null) continue;
                if (imageEditButton.getTag() == null) continue;
                allItems.add(imageEditButton.getTag());
            }
            return allItems;
        }
    
        /**
         * 添加本地图片
         */
        public void addNewImages(List<String> storePaths) {
    
            for (int i = 0; i < storePaths.size(); i++) {
                String path = storePaths.get(i);
                ImageItem imageItem = new ImageItem();
                imageItem.storedPath = path;
                imageItem.id = idValue++;
                Log.i(TAG, "index=" + i + "  id=" + imageItem.id);
                imageItem.index = (buttonsContainer.getChildCount() - 1);
                addBaseImageItemToContainer(imageItem);
    
            }
        }
    
        /**
         * 添加本地图片
         */
        public void addNewImageItem(ImageItem imageItem) {
            if (imageItem == null) return;
            imageItem.id = idValue++;
            imageItem.index = (buttonsContainer.getChildCount() - 1);
            addBaseImageItemToContainer(imageItem);
        }
    
        public void updateEditedImageItem(ImageItem imageItem) {
            ImageEditButton imageEditButton = getImageEditButtonForImageItemById(imageItem);
            if (imageEditButton == null) {
                return;
            }
    
            Object originObj = imageEditButton.getTag();
            if (!(originObj instanceof ImageItem)) {
                if (originObj instanceof RemoteImageItem) {
                    RemoteImageItem remoteItem = (RemoteImageItem) originObj;
                    if (remoteItem.index == imageItem.index) {
                        imageEditButton.setTag(imageItem);
                        imageEditButton.displayUI();
                        return;
                    }
                    reorderForImageItem(imageItem);
                }
                return;
            }
    
            ImageItem originImageItem = (ImageItem) originObj;
            if (imageItem.isDeleted) {
                removeButtonContainImageItem(imageItem);
                resetImageItemIndex();
                return;
            } else {
    
                if (originImageItem.index == imageItem.index) {
                    imageEditButton.setTag(imageItem);
                    imageEditButton.displayUI();
                    return;
                }
                reorderForImageItem(imageItem);
            }
        }
    
    
        /**
         * 添加网络图片
         */
        public void addRemoteImageItem(RemoteImageItem remoteImageItem) {
            addBaseImageItemToContainer(remoteImageItem);
        }
    
        /**
         * 更新网络图片
         */
        public void updateRemoteImageItem(RemoteImageItem remoteImageItem) {
    
            ImageEditButton imageEditButton = getImageEditButtonForImageItemById(remoteImageItem);
            if (imageEditButton == null) {
                if (getAllImageItems().size() > 0) {
                    List<Object> objectList = getAllImageItems();
                    for (int i = 0; i < objectList.size(); i++) {
                        BaseImageItem baseImageItem = (BaseImageItem) objectList.get(i);
                        removeButtonContainImageItem(baseImageItem);
                    }
                    //
                    objectList.add(0, remoteImageItem);
    
                    for (int i = 0; i < objectList.size(); i++) {
                        addRemoteImageItem((RemoteImageItem) objectList.get(i));
                    }
                    //
                } else {
                    addRemoteImageItem(remoteImageItem);
                }
    
                return;
            }
            BaseImageItem baseImageItem = (BaseImageItem) imageEditButton.getTag();
            if (baseImageItem instanceof ImageItem) return;
            RemoteImageItem originRemoteItem = (RemoteImageItem) baseImageItem;
    
            if (remoteImageItem.index == originRemoteItem.index) {
                // index 相同 只是update
                imageEditButton.setTag(remoteImageItem);
                imageEditButton.displayUI();
                return;
            }
            reorderForImageItem(remoteImageItem);
        }
    
        /**
         * 删除网络图片
         */
        public void removeRemoteImageItem(RemoteImageItem remoteImageItem) {
    
            ImageEditButton imageEditButton = getImageEditButtonForImageItemById(remoteImageItem);
            if (null != imageEditButton && null != imageEditButton.getTag()) {
                BaseImageItem baseImageItem = (BaseImageItem) imageEditButton.getTag();
                if (baseImageItem instanceof ImageItem) return;
                RemoteImageItem originRemoteItem = (RemoteImageItem) baseImageItem;
                removeButtonContainImageItem(remoteImageItem);
                resetImageItemIndex();
            }
        }
    
    
        private void reorderForImageItem(BaseImageItem imageItem) {
            removeButtonContainImageItem(imageItem);
            List<BaseImageItem> imageItems = new ArrayList<>();
            imageItems.add(imageItem);
            int count = buttonsContainer.getChildCount();
            for (int i = imageItem.index; i < count; i++) {
                ImageEditButton button = (ImageEditButton) buttonsContainer.getChildAt(i);
                if (button == null) continue;
                BaseImageItem imageItem1 = (BaseImageItem) button.getTag();
                if (imageItem1 == null) continue;
                imageItems.add(imageItem1);
            }
            for (int i = 0; i < imageItems.size(); i++) {
                BaseImageItem item = imageItems.get(i);
                removeButtonContainImageItem(item);
            }
            //
            for (int i = 0; i < imageItems.size(); i++) {
                addBaseImageItemToContainer(imageItems.get(i));
            }
    
        }
    
        private void resetImageItemIndex() {
            for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
    
                try {
                    ImageEditButton button = (ImageEditButton) buttonsContainer.getChildAt(i);
                    if (button == null) continue;
                    BaseImageItem imageItem = (BaseImageItem) button.getTag();
                    if (imageItem == null) continue;
                    imageItem.index = i;
    
                } catch (Exception ignored) {
    
                }
            }
        }
    
    
        private ImageEditButton getImageEditButtonForImageItemById(BaseImageItem imageItem) {
            for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
                ImageEditButton imageEditButton = (ImageEditButton) buttonsContainer.getChildAt(i);
                if (imageEditButton == null) continue;
                if (imageEditButton.getImageItem() == null) continue;
                BaseImageItem searchedImageItem = imageEditButton.getImageItem();
                if (imageItem.id.longValue() == searchedImageItem.id.longValue()) {
                    return imageEditButton;
                }
            }
            return null;
        }
    
    
        /*
        删除一个 ImageItem
         */
        private void removeButtonContainImageItem(BaseImageItem imageItem) {
    
            ImageEditButton imageEditButton = getImageEditButtonForImageItemById(imageItem);
            if (imageEditButton == null) return;
            buttonsContainer.removeView(imageEditButton);
            resetImageItemIndex();
            imbAddImage.setVisibility(buttonsContainer.getChildCount() <= totalImageQuantity ? VISIBLE : GONE);
        }
    
    
        private void addBaseImageItemToContainer(BaseImageItem imageItem) {
            buttonsContainer.removeView(imbAddImage);
    
            ImageEditButton imageEditButton = new ImageEditButton(getContext());
            if (mBtnBgResid != 0)
                imageEditButton.setBtnImageResource(mBtnBgResid);
            imageEditButton.setTag(imageItem);
            imageEditButton.setEditButtonListener(this);
    //        buttonsContainer.addView(imageEditButton, buttonsContainer.getChildCount(), new RelativeLayout.LayoutParams(nSize, imbAddImage.getHeight()));
            buttonsContainer.addView(imageEditButton, buttonsContainer.getChildCount());
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageEditButton.getLayoutParams();
            layoutParams.rightMargin = CommonUtil.dip2px(getContext(), 5);
            imageEditButton.setLayoutParams(layoutParams);
            imageEditButton.setImvHeightAndWidth(imbAddImage.getImvHeight(), imbAddImage.getImvWidth());
            imageEditButton.displayUI();
            //
            buttonsContainer.addView(imbAddImage, buttonsContainer.getChildCount());
            //
            imbAddImage.setVisibility(buttonsContainer.getChildCount() <= totalImageQuantity ? VISIBLE : GONE);
    
            resetImageItemIndex();
    
        }
    
        /*
        ImageEditButton listener
         */
    
        public void doAddImage() {
            if (mEditListener != null) {
                mEditListener.doAddImage();
            }
        }
    
        public void doEditLocalImage(ImageItem imageItem) {
            if (mEditListener != null) {
                mEditListener.doEditLocalImage(imageItem);
            }
    
        }
    
        public void doEditRemoteImage(RemoteImageItem remoteImageItem) {
            if (mEditListener != null) {
                mEditListener.doEditRemoteImage(remoteImageItem);
            }
    
        }
        // -----
    
    
        public void setEditListener(ImageEditContainerListener editListener) {
            this.mEditListener = editListener;
        }
    
        //
    
        public interface ImageEditContainerListener {
            public void doAddImage();
    
            public void doEditLocalImage(ImageItem imageItem1);
    
            public void doEditRemoteImage(RemoteImageItem remoteImageItem);
        }

    项目源码下载:

  • 相关阅读:
    【Web技术】561- 网站性能优化之度量篇
    【拓展】什么是Deno?跟Node.js有何区别?
    【Web技术】560- 一个简洁、有趣的无限下拉方案
    【Web技术】559- 一文带你彻底搞懂跨域
    【TS】558- 5000 多字,让你一文掌握 TS 枚举
    【拓展】你真的会写 Markdown 么?
    【调试】557- 11 个Chrome骚技巧让你为所欲为
    ios 地图
    ios 7 20像素解决
    保存图片到相册
  • 原文地址:https://www.cnblogs.com/dingzq/p/7130317.html
Copyright © 2011-2022 走看看