android 调用相机代码 androidstudio相机教学_Android

功能:调用Android相机拍照,调用系统相册,保存和处理图片。

android 调用相机代码 androidstudio相机教学_android 调用相机代码_02

这是一个很简单的例子,没有好看的UI。

布局很简单:上面三个按钮,下面是个Gridview用来显示获得到的图片,并且点击图片可以实现放大显示效果。


难点1:图片的保存,容易造成OOM异常。

难点2:显示的图片失真的处理。


代码后面会全部给大家,希望大家给予评论。


下面开始详细的讲解。


android 调用相机代码 androidstudio相机教学_android 调用相机代码_03

点击->拍照按钮:   调用系统相机,使用隐式跳转的形式,传入要保存的文件路径,0用来标记是拍照的回调。

     

android 调用相机代码 androidstudio相机教学_android 调用相机代码_04

  我们知道,安卓给每个app只分配1/16 或1/8内存,只要图片稍微大一点,就会出现 out of memory(OOM),所以我们尽量只在内存中保存图片的绝对地址,也就是String,

需要的时候在去缩放,加载。

创建另一个类,专门用来保存图片的绝对路径。因为我们后期图片点击后,会跳转到另一个Activity显示大图,但这两个类都会对图片进行操作,所以创建第三个类,使用静态量

来保存。

           我们规定了GridView显示缩略图,这样我们就要对图片加载的时候做缩放处理了。

android 调用相机代码 androidstudio相机教学_图片_05

android 调用相机代码 androidstudio相机教学_相册_06



拍照后将图片绝对地址保存,在GridView的Adapter的 getView中对图片操作、显示。

布局文件中,对GridView设置为4列,为了确保缩略图的宽度,我们规定每张图的宽度为屏幕的1/5,高度为100dp显示。

计算屏幕的宽度:width = getWindowManager().getDefaultDisplay().getWidth();

工具类:CommonUtils:

android 调用相机代码 androidstudio相机教学_android 调用相机代码_07

需要显示的宽度确定了,我们只要知道原图的宽度,就能算出缩放比例,如果直接加载图片,可能会造成OOM,我们使用BitmapFactory.Options 来获取原图宽度,

并不需要将原图加载到内存中来,防止OOM。


android 调用相机代码 androidstudio相机教学_Android


接下来是相册中选图:

     

Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(path,"temp"+num)));
        startActivityForResult(intent, 1);




在回调中处理:

case 1:        //相册
                Uri uri = data.getData();
                String path3 = changeUriToPath(uri);
                Box.Pics.add(path3);
                mAdapter.notifyDataSetChanged();
                break;





 因为相册中选图后,我们获取到的仅仅是图片的Uri,要将其变成绝对路径,方法如下:

// 将URI转换为真实路径
	private String changeUriToPath(Uri uri) {
		String[] proj = { MediaStore.Images.Media.DATA };
		Cursor actualImageCursor = managedQuery(uri, proj, null, null, null);
		int actual_image_column_index = actualImageCursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		actualImageCursor.moveToFirst();
		String currentImagePath = actualImageCursor
				.getString(actual_image_column_index);
		return currentImagePath;
	}




这样的话,每当我们选一张图或者拍一张图,都会添加到集合中去,然后刷新GridView的Adapter.

接下来要做的就是 点击每一个条目来显示大图效果了,因为要在另一个Activity中显示,我们肯定要将数据带过去,再次建议传递:GridView点击的条目的position,这也是我们

集合中保存的position,方便我们对集合的出来,还不用序列化对象,更快捷。


mGv.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Intent intent = new Intent(getApplicationContext(),ShowPicActivity.class);
                intent.putExtra("pos", position);
                startActivityForResult(intent,2);
            }
        });




mGv:GridView

ShowPicActivity:第三个Activity,用来显示大图的。

第三个Activity布局:


有删除、返回按钮,中间显示图片。

public void back(View v){
		onBackPressed();
	}
	
	public void delete(View v){
		if(pos!=-1){
			Box.Pics.remove(pos);
			finish();
		}
	}




删除集合,然后finish,我们要在跳回去的时候刷新Adapter,来刷新GridView

public void clear(View v){
        File f = new File(path);
        if(f.isDirectory()){
            File[] files = f.listFiles();
            for (File file : files) {
                if(file.isFile()){
                    file.delete();
                }
            }
        }
        Box.Pics.clear();
        mAdapter.notifyDataSetChanged();
    }




相信大家对拍照,获取图片,保存图片都有了解了。 有什么不懂了,欢迎大家留言。