12.android 简单的(6.0、7.0、8.0)相机拍照、相册选图、剪裁。

//第一步 权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

//第二步 依赖,我使用了一个圆形图片库: 

//圆形图片
implementation 'de.hdodenhof:circleimageview:2.1.0'

//第三步 我的Activity布局,就是一个圆形图片:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainPopActivity">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/mCircleImageView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:src="@mipmap/ic_launcher_round" />

</RelativeLayout>

//第四步 Activity代码:

public class MainPopActivity extends AppCompatActivity implements View.OnClickListener {
    //相册请求码
    private static final int ALBUM_REQUEST_CODE = 1;
    //相机请求码
    private static final int CAMERA_REQUEST_CODE = 2;
    //剪裁请求码
    private static final int CROP_SMALL_PICTURE = 3;
    //调用照相机返回图片文件
    private File tempFile;
    //最后显示的图片文件
    private String mFile;

    private Button mPhotograph;
    private Button mAlbum;
    private Button mCancel;
    private PopupWindow window;
    private CircleImageView mCircleImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_pop);
        popUp();
        initView();
        readPictures(); //读取图片,读取上次保存的图片
    }

    //初始化控件,图片点击事件
    private void initView() {
        mCircleImageView = (CircleImageView) findViewById(R.id.mCircleImageView);
        mCircleImageView.setOnClickListener(this);
        mPhotograph.setOnClickListener(this);
        mAlbum.setOnClickListener(this);
        mCancel.setOnClickListener(this);
    }

    //读取图片,设置了图片之后,下次再进来还会有,读取上次保存的图片
    private void readPictures() {
        Bitmap bitmap = BitmapFactory.decodeFile(getPath());
        if (null != bitmap) {
            mCircleImageView.setImageBitmap(bitmap);
        } else {
            mCircleImageView.setImageResource(R.mipmap.ic_launcher);
        }
    }

    //初始化popwindow
    private void popUp() {
        View inflate = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);
        window = new PopupWindow(inflate, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mPhotograph = inflate.findViewById(R.id.mPhotograph);
        window.setAnimationStyle(R.style.popwin_anim_style);//动画
        mAlbum = inflate.findViewById(R.id.mAlbum);
        mCancel = inflate.findViewById(R.id.mCancel);
//        window.setBackgroundDrawable(new BitmapDrawable());//设置PopupWindow的背景
//        window.setOutsideTouchable(false);
        window.setFocusable(true);

        //设置背景颜色变正常
        window.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });
    }

    @Override
    public void onClick(View v) {
        // 设置背景颜色变暗
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.7f;
        getWindow().setAttributes(lp);

        switch (v.getId()) {
            case R.id.mCircleImageView: //图片点击事件,打开popwindow
                //第一个参数是要将PopupWindow放到的View,第二个参数是位置,第三第四是偏移值
                window.showAtLocation(mCircleImageView, Gravity.BOTTOM, 0, 0);
                break;
            case R.id.mPhotograph://拍照
                getPicFromCamera();
                window.dismiss();
                break;
            case R.id.mAlbum://相册
                getPicFromAlbm();
                window.dismiss();
                break;
            case R.id.mCancel://取消
                window.dismiss();
                break;
        }
    }

    //拍照和选择相册的回调
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case CAMERA_REQUEST_CODE:   //调用相机后返回
                if (resultCode == RESULT_OK) {
                    //用相机返回的照片去调用剪裁也需要对Uri进行处理
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        Uri contentUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", tempFile);
                        startPhotoZoom(contentUri);//开始对图片进行裁剪处理
                    } else {
                        startPhotoZoom(Uri.fromFile(tempFile));//开始对图片进行裁剪处理
                    }
                }
                break;
            case ALBUM_REQUEST_CODE:    //调用相册后返回
                if (resultCode == RESULT_OK) {
                    Uri uri = data.getData();
                    startPhotoZoom(uri); // 开始对图片进行裁剪处理
                }
                break;
            case CROP_SMALL_PICTURE:  //调用剪裁后返回
                Bitmap bitmap = BitmapFactory.decodeFile(getPath());
                if (null != bitmap) { // 让刚才选择裁剪得到的图片显示在界面上,清晰
                    mCircleImageView.setImageBitmap(bitmap);
                } else {
                    if (data != null) {// 让刚才选择裁剪得到的图片显示在界面上,模糊
                        Bitmap photo = BitmapFactory.decodeFile(mFile);
                        mCircleImageView.setImageBitmap(photo);
                    } else {
                        Log.e("data", "data=null");
                    }
                }
                break;
        }
    }

    /**
     * 裁剪图片方法实现
     *
     * @param uri
     */
    protected void startPhotoZoom(Uri uri) {
        if (uri == null) {
            Log.i("tag", "The uri is not exist.");
        }
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.setDataAndType(uri, "image/*");
        // 设置裁剪
        intent.putExtra("crop", "true");
        intent.putExtra("scale", true);
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 720);
        intent.putExtra("outputY", 720);
        //设置了true的话直接返回bitmap,可能会很占内存
        intent.putExtra("return-data", false);
        //不启用人脸识别
        intent.putExtra("noFaceDetection", true);
        File out = new File(getPath());
        if (!out.getParentFile().exists()) {
            out.getParentFile().mkdirs();
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
        startActivityForResult(intent, CROP_SMALL_PICTURE);
    }

    //裁剪后的地址,保存到本地
    public String getPath() {
        if (mFile == null) {
            mFile = Environment.getExternalStorageDirectory() + "/" + "MyPicture/" + "temp.png";
        }
        return mFile;
    }

    /**
     * 从相机获取图片
     */
    private void getPicFromCamera() {
        //用于保存调用相机拍照后所生成的文件
//        tempFile = new File(Environment.getExternalStorageDirectory().getPath(), System.currentTimeMillis() + ".png");
        tempFile = new File(Environment.getExternalStorageDirectory().getPath(), "/temp.png");
        //跳转到调用系统相机
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //判断版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {   //如果在Android7.0以上,使用FileProvider获取Uri
            intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
            Log.e("getPicFromCamera", contentUri.toString());
        } else {    //否则使用Uri.fromFile(file)方法获取Uri
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
        }
        startActivityForResult(intent, CAMERA_REQUEST_CODE);
    }

    /**
     * 从相册获取图片
     */
    private void getPicFromAlbm() {
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
        photoPickerIntent.setType("image/*");
        startActivityForResult(photoPickerIntent, ALBUM_REQUEST_CODE);
    }

}

//第五步 我的popwindow布局 pop_layout.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="wrap_content"
    android:orientation="vertical"
    android:id="@+id/mPop"
    >


    <Button
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="@drawable/top_pop_button_bg"
        android:text="拍照"
        android:textColor="#ff0000"
        android:id="@+id/mPhotograph"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <View
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="#d4d4d4"
        android:layout_width="match_parent"
        android:layout_height="1dp"/>

    <Button
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="@drawable/bottom_pop_button_bg"
        android:text="相册"
        android:textColor="#ff0000"
        android:id="@+id/mAlbum"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


    <Button
        android:background="@drawable/cancel_button_bg"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="20dp"
        android:text="取消"
        android:textColor="#0090ff"
        android:id="@+id/mCancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

//第六步 在res下新建anim,在anim下建了两个动画xml文件:

bottom_in.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromYDelta="100%p"
        android:toYDelta="0"
        android:duration="300" />
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1.0"
        android:duration="300"/>
</set>

bottom_out.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromYDelta="0"
        android:toYDelta="100%p"
        android:duration="300"/>

    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0"
        android:duration="300"/>
</set>

//第七步 在res下,values下,style里 添加popwindow动画style:

<style name="popwin_anim_style">
    <item name="android:windowEnterAnimation">@anim/bottom_in</item>
    <item name="android:windowExitAnimation">@anim/bottom_out</item>
</style>

//第八步 在drawable下新建了三个选择圆角背景xml布局文件:

 bottom_pop_button_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">   <!-- 按钮未点击-->
        <shape >
            <solid android:color="#d7d5d5"/>
            <corners android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"/>
        </shape>
    </item>
    <item android:state_pressed="true">  <!-- 按钮选中状态-->
        <shape >
            <solid android:color="#b4b4b4"/>
            <corners android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"/>
        </shape>
    </item>
</selector>

cancel_button_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">   <!-- 按钮未点击-->
        <shape >
        <corners android:radius="10dp" />
        <solid android:color="#d7d5d5"/>
        </shape>
    </item>
    <item android:state_pressed="true">  <!-- 按钮选中状态-->
        <shape >
            <corners android:radius="10dp" />
            <solid android:color="#b4b4b4"/>
        </shape>
    </item>
</selector>

top_pop_button_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">   <!-- 按钮未点击-->
        <shape >
            <solid android:color="#d7d5d5"/>
            <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
        </shape>
    </item>
    <item android:state_pressed="true">  <!-- 按钮选中状态-->
        <shape >
            <solid android:color="#b4b4b4"/>
            <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
        </shape>
    </item>
</selector>

//第九步 Android7.0及以上的需要设置FileProvider,在res下新建xml文件夹,在xml下新建 file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        path="com.example.picturedemo"  name="images" />
    <root-path
        name="root_path"
        path="." />
</paths>

//第十步 在AndroidManifest.xml里注册清单文件,在application下注册,再替换你的包名: 

<!--FileProvider共享文件、缓存-->
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="你的包名.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

//简洁重要方法:

/**
 * 相册请求码
 */
private static final int ALBUM_REQUEST_CODE = 1;

/**
 * 相机请求码
 */
private static final int CAMERA_REQUEST_CODE = 2;

/**
 * 剪裁请求码
 */
private static final int CROP_SMALL_PICTURE = 3;

/**
 * 调用照相机返回图片文件
 */
private File tempFile;

/**
 * 裁剪后的地址,保存到本地
 */
private String filePath = "";


public File getTempFile() {
    if (null == tempFile) {
        tempFile = new File(Environment.getExternalStorageDirectory().getPath(), "/temp.png");
    }
    return tempFile;
}

//拍照和选择相册的回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        //调用相机后返回
        case CAMERA_REQUEST_CODE:
            if (resultCode == RESULT_OK) {
                //用相机返回的照片去调用剪裁也需要对Uri进行处理
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    Uri contentUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", getTempFile());
                    //开始对图片进行裁剪处理
                    startPhotoZoom(contentUri);
                } else {
                    //开始对图片进行裁剪处理
                    startPhotoZoom(Uri.fromFile(getTempFile()));
                }
            }
            break;
        //调用相册后返回
        case ALBUM_REQUEST_CODE:
            if (resultCode == RESULT_OK) {
                Uri uri = data.getData();
                //开始对图片进行裁剪处理
                startPhotoZoom(uri);
            }
            break;
        //调用剪裁后返回
        case CROP_SMALL_PICTURE:
            Bitmap bitmap = BitmapFactory.decodeFile(getPath());
            //让刚才选择裁剪得到的图片显示在界面上,清晰
            mMyInfoImg.setImageBitmap(bitmap);
            adapter.addData(getPath());
            addPicData();
            filePath = "";
            if (null!=getTempFile()){
                tempFile.delete();
            }
            break;
        default:
            break;
    }
}

/**
 * 裁剪图片方法实现
 *
 * @param uri
 */
private void startPhotoZoom(Uri uri) {
    if (uri == null) {
        Log.i("tag", "The uri is not exist.");
    }
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    intent.setDataAndType(uri, "image/*");
    // 设置裁剪
    intent.putExtra("crop", "true");
    intent.putExtra("scale", true);
    // aspectX aspectY 是宽高的比例
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    // outputX outputY 是裁剪图片宽高
    intent.putExtra("outputX", 720);
    intent.putExtra("outputY", 720);
    //设置了true的话直接返回bitmap,可能会很占内存
    intent.putExtra("return-data", false);
    //不启用人脸识别
    intent.putExtra("noFaceDetection", true);
    File out = new File(getPath());
    if (!out.getParentFile().exists()) {
        out.getParentFile().mkdirs();
    }
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
    startActivityForResult(intent, CROP_SMALL_PICTURE);
}


/**
 * 裁剪后的地址,保存到本地
 *
 * @return
 */
public String getPath() {
    if (TextUtils.isEmpty(filePath)) {
        filePath = Environment.getExternalStorageDirectory() + "/recorderPhone/picture/" + DateTimeUtil.getInstance().getNowLongTime() + ".png";
    }
    return filePath;
}

/**
 * 从相机获取图片
 */
private void getPicFromCamera() {
    //跳转到调用系统相机
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //判断版本 如果在Android7.0以上,使用FileProvider获取Uri,否则使用Uri.fromFile(file)方法获取Uri
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        Uri contentUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", getTempFile());
        intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
    } else {
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile()));
    }
    startActivityForResult(intent, CAMERA_REQUEST_CODE);
}

/**
 * 从相册获取图片
 */
private void getPicFromAlbm() {
    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
    photoPickerIntent.setType("image/*");
    startActivityForResult(photoPickerIntent, ALBUM_REQUEST_CODE);
}

//-------------------------------------------------------------------------------完-----------------------------------------------------------------------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值