安卓仿微信朋友圈拍照获取照片,压缩照片,显示上传,可以预览根据手势放大与缩小图片

13 篇文章 0 订阅

最近项目要求做一个仿微信朋友圈拍照获取照片显示上传,要对图片进行压缩处理,防止OOM,废话不多说,下面进行拍照功能实现:

实现效果如图:

1.选择界面:

    

预览界面(可以根据手势放大缩小):


已经封装成一个lib包,直接添加项目依赖就能使用:

下载依赖包地址源码:

https://download.csdn.net/download/zqr772791008/10300742

项目大概长这样:


对类的说明:

  1. Constatnt:拍照功能的一些基础参数配置
  2. IMakePic:图片压缩获取成功以后的回调接口;
  3. MakePhotoAdapter:九宫格适配器
  4. PhotoFileUtils:照片文件处理器
  5. TakePhotoUtil:拍照的工具类
  6. imagezoom: 根据手势放大与缩小的包

开始之前记得添加权限:

<!-- SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- SD卡权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--拍照的权限-->
<uses-permission android:name="android.permission.CAMERA"/>

<application>
    <activity
        android:name="com.zoesoft.mobile.imagezoom.activity.ImagePagerActivity"
        >
    </activity>
</application>

使用方法例子:

package com.example.administrator.myapplication.photo;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.example.administrator.myapplication.R;

import java.util.ArrayList;

public class photoActivity extends AppCompatActivity implements IMakePic {

    RecyclerView mRecyclerView;

    MakePhotoAdapter mMakePicAdapter;

    ArrayList<String> photoInfos = new ArrayList<>();

    TakePhotoUtil takePhotoUtil;

    // 相机取图
    private static final int CAMERA_WITH_DATA = 1000;
    private String imageUrl;
    private Uri imageUri;

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

        mRecyclerView = (RecyclerView) findViewById(R.id.rv_addphoto);

        takePhotoUtil = new TakePhotoUtil(CAMERA_WITH_DATA,this,this);
        //图片列表
        GridLayoutManager mLayoutManager = new GridLayoutManager(this, 3);
        mRecyclerView.setLayoutManager(mLayoutManager);


        mMakePicAdapter = new MakePhotoAdapter(this, photoInfos, this, Constatnt.EDIT);
        mMakePicAdapter.setMaxCount(9);
        mRecyclerView.setAdapter(mMakePicAdapter);

    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

            if (requestCode == CAMERA_WITH_DATA && resultCode == RESULT_OK ) {
//                luban();
                takePhotoUtil.luBanCompress();//压缩图片
            }

    }








    @Override
    public void takePic() {
//        doTakePhoto();
        takePhotoUtil.doTakePhoto();//开启相机
}

    @Override
    public void onImageUpload(String url) {
        photoInfos.add(url);
        Log.e("photoInfos的大小",""+photoInfos.size());
        mMakePicAdapter.setDataList(photoInfos);
    }


}




关键代码:

1.Constatnt类:

package com.example.administrator.myapplication.photo;



public class Constatnt {
    
    /**
     * 图片显示的最大数量
     */
    public static final int MAX_COUNT = 9;
    
    /**
     * 是否显示增加按钮
     */
    public static final int ITEM_ADD = 0;
    
    public static final int ITEM_CONTENT = 1;
    
    /**
     * 显示图片
     */
    public static final int SHOW = 10000;
    
    /**
     * 编辑图片
     */
    public static final int EDIT = 20000;
    
}

2.IMakePic:

package com.example.administrator.myapplication.photo;


 
public interface IMakePic {



    /**
     * 拍照片
     */
    void takePic();


    /**
     * 图片压缩获取成功以后的回调接口
     */
        void onImageUpload(String url);
}

3.MakePhotoAdapter:

package com.example.administrator.myapplication.photo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.example.administrator.myapplication.R;
import com.example.administrator.myapplication.photo.imagezoom.util.ImageZoom;
import com.nostra13.universalimageloader.core.download.ImageDownloader;

import java.util.ArrayList;
import java.util.List;



public class MakePhotoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context mContext = null;

    private LayoutInflater mInflater = null;

    List<String> mPhotoInfoList = new ArrayList<>();

    private IMakePic mMakePic = null;

    /**
     * 显示还是编辑
     */
    private int type = Constatnt.SHOW;

    /**
     * 图片选取的最大数量,当达到最大数量是,不显示增加按钮
     */
    private int maxCount = Constatnt.MAX_COUNT;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getMaxCount() {
        return maxCount;
    }

    public void setMaxCount(int maxCount) {
        this.maxCount = maxCount;
    }

    public MakePhotoAdapter(Context context, List<String> photoInfoList, IMakePic makePic) {
        this(context, photoInfoList, makePic, Constatnt.EDIT);
    }

    public MakePhotoAdapter(Context context, List<String> photoInfoList, IMakePic makePic, int type) {
        mContext = context;
        mPhotoInfoList = photoInfoList;
        mMakePic = makePic;
        this.type = type;
        mInflater = LayoutInflater.from(mContext);
    }

    /**
     * 判断是否需要显示一个增加按钮,当达到最大数量是不显示增加按钮
     * @return
     */
    @Override
    public int getItemCount() {
        if (getType() == Constatnt.SHOW) {
            return mPhotoInfoList.size();
        }
        else {
            int num = mPhotoInfoList.size();
            return num == getMaxCount() ? getMaxCount() : ++num;
        }
    }

    /**
     * 判断选择哪种布局,一种是显示布局,一种是增加布局(有删除按钮)
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        if (getType() == Constatnt.SHOW) {
            return Constatnt.ITEM_CONTENT;
        }
        else {
            if (position == mPhotoInfoList.size()) {
                return Constatnt.ITEM_ADD;
            }
            return Constatnt.ITEM_CONTENT;
        }
    }

    /**
     * 返回列表数据
     *
     * @return
     */
    public List<String> getDataList() {
        return this.mPhotoInfoList;
    }

    /**
     * 更新数据集
     * @param dataList
     */
    public void setDataList(ArrayList<String> dataList) {
        mPhotoInfoList = dataList;
        notifyDataSetChanged();
    }



    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (getType() == Constatnt.SHOW) {
            return new ContentViewHolder(mInflater.inflate(R.layout.item_adapter_photo_list, parent, false));
        }
        else {
            if (viewType == Constatnt.ITEM_ADD) {
                return new AddViewHolder(mInflater.inflate(R.layout.item_photo_add, parent, false));
            }
            else {
                return new ContentViewHolder(mInflater.inflate(R.layout.item_adapter_photo_list, parent, false));
            }
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {



            //显示图片数据
            if (holder instanceof ContentViewHolder) {
                String path =mPhotoInfoList.get(position) ;
                if (path.contains("storage")) {
                    path =ImageDownloader.Scheme.FILE.wrap(path);
                }
                //加载图片
                Glide.with(mContext).load(path).into(((ContentViewHolder) holder).mIvPhoto);
                //图片右上角显示删除按钮
                ((ContentViewHolder) holder).mIvDelete.setVisibility(View.VISIBLE);
                final String finalPath = path;

                //删除按钮操作
                ((ContentViewHolder) holder).mIvDelete.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        getDataList().remove(holder.getLayoutPosition());
                        notifyDataSetChanged();

                    }
                });

                //查看预览图
                ((ContentViewHolder) holder).mIvPhoto.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
//                        ImageZoom.show(mContext, finalPath, ImageZoom.LOCAL);
                        ImageZoom.show(mContext, position,mPhotoInfoList );
                    }

                });
            }
            else if (holder instanceof AddViewHolder) {
                //显示添加按钮
                ((AddViewHolder) holder).mImageAdd.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mMakePic != null)
                        mMakePic.takePic();
                    }

                });
            }

    }

    public static class AddViewHolder extends RecyclerView.ViewHolder {

        ImageView mImageAdd;

        public AddViewHolder(View footView) {
            super(footView);
            mImageAdd = (ImageView) itemView.findViewById(R.id.imageviewadd);
        }

    }

    public static class ContentViewHolder extends RecyclerView.ViewHolder {

        ImageView mIvPhoto;

        ImageView mIvDelete;

        public ContentViewHolder(View itemView) {
            super(itemView);
            mIvPhoto = (ImageView) itemView.findViewById(R.id.iv_photo);
            mIvDelete = (ImageView) itemView.findViewById(R.id.iv_delete);
        }

    }
}

4.PhotoFileUtils:

package com.example.administrator.myapplication.photo;

import android.os.Environment;
import android.text.TextUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PhotoFileUtils {

    private static String rootPath = "TakePhoto";
    private static String playPath = "";
    private final static String PHOTO_JPG_BASEPATH = "/" + rootPath + "/img/";
    private final static String PHOTO_COMPRESS_JPG_BASEPATH = "/" + rootPath + "/CompressImg/";

    public static void setRootPath(String rootPath) {
        PhotoFileUtils.rootPath = rootPath;
    }


    //获取保存原始文件的位置
    public static String getJpgFileAbsolutePath(String fileName) {
        if (TextUtils.isEmpty(fileName)) {
            throw new NullPointerException("fileName isEmpty");
        }
        String photoPath = "";
        if (!fileName.endsWith(".jpg")) {
            fileName = fileName + ".jpg";
        }
        String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + PHOTO_JPG_BASEPATH;
        File file = new File(fileBasePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        photoPath = fileBasePath + fileName;

        return photoPath;
    }

    // //获取保存压缩图片文件的位置
    public static String getCompressJpgFileAbsolutePath(){
        String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + PHOTO_COMPRESS_JPG_BASEPATH;
        File file = new File(fileBasePath);
        if (!file.exists()) {
            file.mkdirs();
        }

       return fileBasePath;
    }


    /**
     * 获取全部压缩jpg文件列表
     *
     * @return
     */
    public static List<File> getJpgFiles() {
        List<File> list = new ArrayList<>();
        String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + PHOTO_COMPRESS_JPG_BASEPATH;

        File rootFile = new File(fileBasePath);
        if (!rootFile.exists()) {
        } else {
            File[] files = rootFile.listFiles();
            for (File file : files) {
                list.add(file);
            }

        }
        Collections.reverse(list); //倒序排列
        return list;
    }


    /**
     * 获取全部压缩jpg文件列表
     *
     * @return
     */
    public static List<String> getPcmFilesPath() {
        List<String> list = new ArrayList<>();
        String fileBasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + PHOTO_COMPRESS_JPG_BASEPATH;

        File rootFile = new File(fileBasePath);
        if (!rootFile.exists()) {
        } else {
            File[] files = rootFile.listFiles();
            for (File file : files) {
                list.add(file.getPath());
            }

        }
        Collections.reverse(list); //倒序排列
        return list;
    }



}

5.TakePhotoUtil:

package com.example.administrator.myapplication.photo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.ActionMenuView;
import android.widget.Toast;

import java.io.File;

import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * Created by Administrator on 2017/12/28.
 */

public class TakePhotoUtil {
     private Activity mContext;
    private String imageUrl;//照片的url
    private Uri imageUri;//照片的uri
    private IMakePic iMakePic;
    private int mRequestCode;
    /**
     * 图片压缩获取成功以后的回调接口
     */


    public  TakePhotoUtil(int requestCode,Context context, IMakePic imakePic) {
        this.mContext = (Activity) context;
        this.iMakePic = imakePic;
        this.mRequestCode = requestCode;
    }


    //    开启相机
    public void doTakePhoto() {
        String SDState = Environment.getExternalStorageState();
        if(SDState.equals(Environment.MEDIA_MOUNTED))
        {
            imageUrl = PhotoFileUtils.getJpgFileAbsolutePath( System.currentTimeMillis() + ".jpg");
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            imageUri = Uri.fromFile(new File(imageUrl));
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            mContext.startActivityForResult(intent, mRequestCode);
        }else {
            Toast.makeText(mContext, "内存卡不存在!",Toast.LENGTH_LONG).show();
        }

    }


    //压缩图片
    public void luBanCompress(){
        Luban.with(mContext)
                .load(new File(imageUrl))
                .putGear(3)//设置压缩级别 默认是3
                .setTargetDir(PhotoFileUtils.getCompressJpgFileAbsolutePath())
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {

                    }
                    @Override
                    public void onSuccess(File file) {
                        Log.e("path", file.getAbsolutePath());
                        Log.e("压缩以后file大小", file.length()+"");
                        File oldfile = new File(imageUrl);//删掉旧文件
                        if (oldfile.exists()) {
                            oldfile.delete();
                        }
                        if (iMakePic != null){
                            iMakePic.onImageUpload(file.getAbsolutePath());
                        }
//                        photoInfos.add(file.getAbsolutePath());
//                        Log.e("photoInfos的大小",""+photoInfos.size());
//                        mMakePicAdapter.setDataList(photoInfos);
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                })
                .launch();
    }

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值