功能:调用Android相机拍照,调用系统相册,保存和处理图片。
这是一个很简单的例子,没有好看的UI。
布局很简单:上面三个按钮,下面是个Gridview用来显示获得到的图片,并且点击图片可以实现放大显示效果。
难点1:图片的保存,容易造成OOM异常。
难点2:显示的图片失真的处理。
代码后面会全部给大家,希望大家给予评论。
下面开始详细的讲解。
点击->拍照按钮: 调用系统相机,使用隐式跳转的形式,传入要保存的文件路径,0用来标记是拍照的回调。
我们知道,安卓给每个app只分配1/16 或1/8内存,只要图片稍微大一点,就会出现 out of memory(OOM),所以我们尽量只在内存中保存图片的绝对地址,也就是String,
需要的时候在去缩放,加载。
创建另一个类,专门用来保存图片的绝对路径。因为我们后期图片点击后,会跳转到另一个Activity显示大图,但这两个类都会对图片进行操作,所以创建第三个类,使用静态量
来保存。
我们规定了GridView显示缩略图,这样我们就要对图片加载的时候做缩放处理了。
拍照后将图片绝对地址保存,在GridView的Adapter的 getView中对图片操作、显示。
布局文件中,对GridView设置为4列,为了确保缩略图的宽度,我们规定每张图的宽度为屏幕的1/5,高度为100dp显示。
计算屏幕的宽度:width = getWindowManager().getDefaultDisplay().getWidth();
工具类:CommonUtils:
需要显示的宽度确定了,我们只要知道原图的宽度,就能算出缩放比例,如果直接加载图片,可能会造成OOM,我们使用BitmapFactory.Options 来获取原图宽度,
并不需要将原图加载到内存中来,防止OOM。
接下来是相册中选图:
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();
}
相信大家对拍照,获取图片,保存图片都有了解了。 有什么不懂了,欢迎大家留言。