拍照/从相册读取图片后进行裁剪的方法
本范例实现的是用户可以通过拍照、相册获取图片,然后进行裁剪,最后将结果保存在IamgeView中。当然你可以选择将结果同时存放在sd卡中,作为以后的缓存。
思路:
1.通过拍照获取图片
进入系统自带的相机界面——>拍照——>保存在sd卡中——>读取sd卡的文件进行裁减。PS:裁剪前先判断是否获取到图片了
2.通过系统相册获取图片
进入系统相册——>找到图片——>进行裁减。PS:裁剪前线判断是否获取到系统的图片了
接下来贴上实现方法:
1.进入拍照界面或者相册的方法,获取信息后回调onActivityResult()方法
public void buttonListener(View v) { switch (v.getId()) { case R.id.fromAlbum_button: // 来自相册 Intent albumIntent = new Intent(Intent.ACTION_PICK, null); /** * 下面这句话,与其它方式写是一样的效果,如果: * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); * intent.setType(""image/*");设置数据类型 * 要限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型" */ albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(albumIntent, ALBUM_OK); break; case R.id.fromCamera_button: // 来自相机 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 下面这句指定调用相机拍照后的照片存储的路径 cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(cameraIntent, CAMERA_OK);// CAMERA_OK是用作判断返回结果的标识 break; default: break; } }
2.得到信息,交给onActivityResult()处理。先判断是否得到信息,如果得到就进行裁剪。
在这里需要注意的是从相册返回的结果存到的是data里面,拍照后的图片结果存放的是file文件。由于从相册取到的图片可能很大,所以系统会经过一定的压缩,data得到的图片有可能失真。具体问题有待实际解决。而拍照后的图片来源是文件,所以应该不会有什么问题。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { System.out.println("requestCode = " + requestCode); switch (requestCode) { // 如果是直接从相册获取 case ALBUM_OK: //从相册中获取到图片了,才执行裁剪动作 if (data != null) { clipPhoto(data.getData()); } break; // 如果是调用相机拍照时 case CAMERA_OK: // 当拍照到照片时进行裁减,否则不执行操作 if (file.exists()) { clipPhoto(Uri.fromFile(file));//开始裁减图片 } break; // 取得裁剪后的图片,这里将其设置到imageview中 case CUT_OK: /** * 非空判断大家一定要验证,如果不验证的话, 在剪裁之后如果发现不满意, * 要重新裁剪,丢弃 当前功能时,会报NullException */ if (data != null) { setPicToView(data); } break; default: break; } super.onActivityResult(requestCode, resultCode, data); }
3.进行图片裁剪的方法:
如果在裁剪时返回的图片很大,系统会强行进行裁剪。
/** * 裁剪图片方法实现 * @param uri */ public void clipPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 下面这个crop = true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例,这里设置的是正方形(长宽比为1:1) intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 200); intent.putExtra("outputY", 200); intent.putExtra("return-data", true); startActivityForResult(intent, CUT_OK); }
4.将裁剪好的图片设置到ImageView中,同时清除缓存图片
/** * 保存裁剪之后的图片数据 将图片设置到imageview中 * * @param picdata */ private void setPicToView(Intent picdata) { Bundle extras = picdata.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); Drawable drawable = new BitmapDrawable(photo); showIv.setImageDrawable(drawable); file.delete();//设置成功后清除之前的照片文件 } }
最后贴上全部的代码:
package com.kale.picturecut; import java.io.File; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.widget.ImageView; public class MainActivity extends Activity { // 拍照成功,读取相册成功,裁减成功 private final int ALBUM_OK = 1, CAMERA_OK = 2,CUT_OK = 3; private ImageView showIv; private File file; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 定义拍照后存放图片的文件位置和名称,使用完毕后可以方便删除 file = new File(Environment.getExternalStorageDirectory(), "temp.jpg"); file.delete();// 清空之前的文件 showIv = (ImageView) findViewById(R.id.show_imageView); } public void buttonListener(View v) { switch (v.getId()) { case R.id.fromAlbum_button: // 来自相册 Intent albumIntent = new Intent(Intent.ACTION_PICK, null); /** * 下面这句话,与其它方式写是一样的效果,如果: * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); * intent.setType(""image/*");设置数据类型 * 要限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型" */ albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(albumIntent, ALBUM_OK); break; case R.id.fromCamera_button: // 来自相机 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 下面这句指定调用相机拍照后的照片存储的路径 cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(cameraIntent, CAMERA_OK);// CAMERA_OK是用作判断返回结果的标识 break; default: break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { System.out.println("requestCode = " + requestCode); switch (requestCode) { // 如果是直接从相册获取 case ALBUM_OK: //从相册中获取到图片了,才执行裁剪动作 if (data != null) { clipPhoto(data.getData()); } break; // 如果是调用相机拍照时 case CAMERA_OK: // 当拍照到照片时进行裁减,否则不执行操作 if (file.exists()) { clipPhoto(Uri.fromFile(file));//开始裁减图片 } break; // 取得裁剪后的图片,这里将其设置到imageview中 case CUT_OK: /** * 非空判断大家一定要验证,如果不验证的话, 在剪裁之后如果发现不满意, * 要重新裁剪,丢弃 当前功能时,会报NullException */ if (data != null) { setPicToView(data); } break; default: break; } super.onActivityResult(requestCode, resultCode, data); } /** * 裁剪图片方法实现 * @param uri */ public void clipPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 下面这个crop = true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例,这里设置的是正方形(长宽比为1:1) intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 200); intent.putExtra("outputY", 200); intent.putExtra("return-data", true); startActivityForResult(intent, CUT_OK); } /** * 保存裁剪之后的图片数据 将图片设置到imageview中 * * @param picdata */ private void setPicToView(Intent picdata) { Bundle extras = picdata.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); Drawable drawable = new BitmapDrawable(photo); showIv.setImageDrawable(drawable); file.delete();//设置成功后清除之前的照片文件 } } }
权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.per
源码下载:http://download.csdn.net/detail/shark0017/7964819
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?