Android拍照、裁剪与相册处理

为了专注技术开发,与开发中的经验总结,我赖坤奇决定从今天开始分享Java、Android开发过程中的一点经验,算记录开发过程中历程,方便以后回顾,也希望遇到大牛多加指点。共同进步。


这篇文章实现的是如何使用Android来实现应用内打开相册、打开照相机拍照并按要求裁剪保存的干货,分享给各位。


首先,需要在Manifest文件目录中添加权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
    <uses-permission android:name="android.permission.CAMERA" />
需要用到写、读SD卡,打开照相机等权限。

在MainActivity的布局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">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="拍照"
        android:onClick="onCapture"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="从相册获取"
        android:onClick="onChoose"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/iv"/>
</LinearLayout>
在Android系统中,多媒体库是通过MediaScanner去扫描磁盘文件,对元信息的处理,并通过MediaProvider保存到MediaStore中。下图为MediaScannerr 框架:


媒体文件可以存储在手机终端的内存中,也可以存储在SD卡中,Android平台中称手机终端内存为内部存储空间,称SD卡为外部存储空间。针对内部和外部存储空间中的媒体文件信息是分开管理的,各自有独立的数据库管理。因此在扫描媒体文件时,要明确指明扫描的媒体文件是位于内部存储空间还是外部存储空间。外部存储空间和内部存储空间对应的卷标为”external”和”internal”。

学习过ContentProvider,对于图像(以及音频和视频)的标准内容提供器是MediaStore,MediaStore类是Android平台的多媒体数据库,它包含了音频,视频,图片等所有多媒体文件信息。本文将重点介绍如何管理和获取音频信息,视频和图片等信息的获取与管理与音频类似。

废话不多说,直接上MainActivity的代码实现:

在activity中声明控件与定义常量请求码等成员变量。

      private ImageView miv;
    /** 拍照后保存图片的路径*/
    File mFile;
      //定义requestCode
    static final int ACTION_CAPTURE=1;
    static final int ACTION_CHOOSE=2;
    static final int ACTION_CROP=3;
在onCreate中初始化控件,并未两个Button控件添加点击事件。设置意图action为MediaStore.ACTION_IMAGE_CAPTURE,同时设置输出流,拍照保存位置,文件位置为外部sd卡图片存放目录,名称为系统当前时间毫秒值,即给意图附加值

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mFile));
最后使用startActivityForResult()方法发送意图,打开拍照的activity。

打开相册activity同样如下:

MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"
具体代码为:

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

    private void initView() {
        miv = (ImageView) findViewById(R.id.iv);
    }

    /**
     * 拍照按钮的点击事件响应
     * @param view
     */
    public void onCapture(View view) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        mFile= new File(dir, System.currentTimeMillis() + "");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mFile));
        startActivityForResult(intent,ACTION_CAPTURE);
    }

    /**
     * 相册选取按钮的点击事件响应
     * @param view
     */
    public void onChoose(View view) {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(intent, ACTION_CHOOSE);
    }

在Activity中复写onActivityResult(int requestCode, int resultCode, Intent data)方法,对拍照,相册的intent中对数据进行处理。根据requestCode进行分类处理,并使用安卓系统自带裁剪activity对托片进行处理。具体代码如下:

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (RESULT_OK != resultCode) {
            return;
        }
        switch (requestCode) {
            case ACTION_CAPTURE:
                Log.i("main","拍照完毕,结果保存在:"+mFile.getAbsolutePath());
                //启动系统裁剪的Activity
                startCropActivity(Uri.fromFile(mFile),200,200,ACTION_CROP);
                break;
            case ACTION_CHOOSE:
                Log.i("main","相册选取完毕");
                //启动系统裁剪的Activity
                startCropActivity(data.getData(),200,200,ACTION_CROP);
                break;
            case ACTION_CROP:
                showPhoto(data);
                break;
        }
    }
裁剪的方法实现,设置intent的action为com.android.camera.action.CROP,根据系统预定好的key值为intent设定value,传递给系统自带裁剪活动。

private void startCropActivity(Uri uri, int outputX, int outputY, int requestCode) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("outputX",outputX);
        intent.putExtra("outputY", outputY);
        //保存裁剪的结果
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        //设置是否返回数据
        intent.putExtra("return-data", true);
        //设置保存图片的类型
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(intent,requestCode);

    }

把裁剪后返回的intent中获取data进行imageView的展示,方法如下:

private void showPhoto(Intent data) {
        Bundle extras = data.getExtras();
        Bitmap bitmap = extras.getParcelable("data");
        miv.setImageBitmap(bitmap);
    }
好了,安卓开发程序猿小赖,第一次展示开发的经验干货送上,希望对各位开发有点帮助!!

可加本人QQ:781548819,方便交流。我会持续不断的吧自己安卓开发中的一些东西分享出来,也方便自己的成长。谢谢!!~~







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值