【Android】【超简单】让你学会相机拍照,相册选图,OOM处理等

本文详细讲解了如何在Android应用中实现相机拍照和相册选择功能,包括图片保存、显示与处理,避免内存泄漏的方法以及点击图片放大显示效果。通过布局设计和适配不同屏幕尺寸,确保了图片的清晰显示。同时提供了图片路径转换方法,便于后续操作。此外,还实现了从GridView点击图片到显示大图的交互体验,包括图片删除和返回功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能:调用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();
    }


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

下面是代码下载地址:http://download.youkuaiyun.com/detail/youngerprogramer/9305205



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值