Android调用相机进行拍照,调用图库获取图片,可进行裁剪,显示图片,并将图片上传文章来源地址https://www.toymoban.com/news/detail-513822.html
public static final int PHOTO_REQUEST_CAREMA = 1;//拍照
public static final int CROP_PHOTO = 2;//裁剪
public static final int PHOTO_ALBUM = 3;//相册
private Intent intentPhoto;
private Uri image_uri;
private Uri album_uri;
private MeMoryBitmap meMoryBitmap;
private static File tempFile,album_tempFile;
private static final String TAG="RegisterActivity";
//拍照
private void openCamera() {
Bitmap bitmap=null;
ivPhotoshow.setImageBitmap(bitmap);
//调用方法,解决内存泄露
meMoryBitmap.recycleImageView(ivPhotoshow);
//获取操作系统的版本号
int currentapiVersion= Build.VERSION.SDK_INT;
//MediaStore.ACTION_IMAGE_CAPTURE调用系统相机拍照
intentPhoto=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(hasSdcard()){
//获取时间戳
SimpleDateFormat timeStampFormat=new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
String filename=timeStampFormat.format(new Date());
//获取外部存储根目录Environment.getExternalStorageDirectory()方法已经过时,改用context.getExternalFilesDir(null).getAbsolutePath()
tempFile=new File(Environment.getExternalStorageDirectory(),
filename+".jpg");
if(currentapiVersion<24){
image_uri=Uri.fromFile(tempFile);
//MediaStore.EXTRA_OUTPUT规避Intent携带信息的不靠谱
intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
}else{
//兼容android7.0 使用共享文件的形式.ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,
// contenvalues只能存储基本类型的数据,像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象。
ContentValues contentValues=new ContentValues(1);
//获取文件
contentValues.put(MediaStore.Images.Media.DATA,tempFile.getAbsolutePath());
//判断应用是否授予权限
if(ContextCompat.checkSelfPermission(RegisterActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
String[] PERMISSIONS={"android.permission.CAMERA","android.permission.WRITE_EXTERNAL_STORAGE"};
//权限申请结果
ActivityCompat.requestPermissions(RegisterActivity.this,PERMISSIONS,1);
return;
}
//getContext().getContentResolver().insert(...);
/**
* getContext()是获得一个上下文对象(Context),一般在四大组件中都会获取上下文对象
* 在Activity和Service中,就没必要获取Context了,因为他本身就是,所以可以直接调用getContentResolver()。
* getContext().getContentResolver()返回的是ContentResolver 对象,ContentResolver负责获取ContentProvider提供的数据。
* 将图片保存至相册
*/
image_uri=getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
}
}
/**
* 在Activity中得到新打开Activity 关闭后返回的数据,
* 需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,
* 新的Activity 关闭后会向前面的Activity传回数据,为了得到传回的数据,
* 必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法
*/
startActivityForResult(intentPhoto,PHOTO_REQUEST_CAREMA,null);
}
//调用图库
private void openAlbum() {
Bitmap bitmap=null;
ivPhotoshow.setImageBitmap(bitmap);
//获取时间戳
SimpleDateFormat timeStampFormat=new SimpleDateFormat(
"yyyy_MM_dd_HH_mm_ss"
);
String filename=timeStampFormat.format(new Date());
//图片命名
album_tempFile=new File(Environment.getExternalStorageDirectory(),filename+".jpg");
if(album_tempFile.exists()){
album_tempFile.delete();
}else {
/**
* 创建目录的方式大致有这两种情况,这两种情况的区别是
* 1. mkdir():根据相对路径创建目录,只会在原有的目录里面创建,如果上面一级的目录xxdir不存在,则这次创建便会失败, 报xxxdir这个目录找不到的异常
* 2. mkdirs():根据绝对路径新建目录,如果上一级目录不存在,则会将上一级目录创建完后,再创建后面一级的目录
*/
album_tempFile.mkdirs();
}
try {
album_tempFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//Uri.parse("file://" + new File(path).toString())==Uri.fromFile(new File(path))
album_uri=Uri.fromFile(album_tempFile);
Intent intent_album=null;
//判断操作系统版本
if(Build.VERSION.SDK_INT<19){
//ACTION_GET_CONTENT:允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)调用图库,获取所有本地图片
intent_album=new Intent(Intent.ACTION_GET_CONTENT);
/**
* 正常的访问系统自带的文件管理器。但是setType只支持单个setType一般是以下这种 intent_album.setType("image/*");
* 我要限制只查看ppt ,doc,docx,pptx,pdf等文件
* public static final String DOC = "application/msword";
* public static final String DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
* public static final String XLS = "application/vnd.ms-excel application/x-excel";
* public static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
* public static final String PPT = "application/vnd.ms-powerpoint";
* public static final String PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
* public static final String PDF = "application/pdf";
*
* try {
* Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
* intent.addCategory(Intent.CATEGORY_OPENABLE);
* //设置doc,docx,ppt,pptx,pdf 5种类型
* intent.setType("application/msword|application/vnd.openxmlformats-officedocument.wordprocessingml.document" +
* "|application/vnd.ms-powerpoint|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/pdf");
* //在API>=19之后设置多个类型采用以下方式,setType不再支持多个类型
* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
* intent.putExtra(Intent.EXTRA_MIME_TYPES,
* new String[]{DOC,DOCX, PPT, PPTX,PDF});
* }
* startActivityForResult(intent, 1001);
* } catch (ActivityNotFoundException e) {
* }
*/
intent_album.setType("image/*");
}else{
/**
* 一、调用图库,获取所有本地图片:
* Intent imageIntent = new Intent(Intent.ACTION_GET_CONTENT);
* imageIntent.setType("image/*");
* startActivityForResult(imageIntent, PICK_CODE); //PICK_CODE是常量
* 二、调用本地联系人:
* Intent intent = new Intent(Intent.ACTION_PICK);
* intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
* startActivityForResult(intent, PICK_CONTACT);
* 三、调用音乐,获取所有本地音乐文件:
* Intent audioIntent = new Intent(Intent.ACTION_GET_CONTENT);
* audioIntent.setType("audio/*");
* startActivityForResult(audioIntent, PICK_AUDIO);
* 四、调用视频,获取所有本地视频文件:
* Intent videoIntent = new Intent(Intent.ACTION_GET_CONTENT);
* videoIntent.setType("video/*");
* startActivityForResult(videoIntent, PICK_VIDEO);
*/
intent_album=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
//允许裁剪
intent_album.putExtra("crop",true);
//允许缩放
intent_album.putExtra("scale",true);
//图片的输出位置
intent_album.putExtra(MediaStore.EXTRA_OUTPUT,album_uri);
startActivityForResult(intent_album,PHOTO_ALBUM);
}
//判断sdcard是否被挂载,判断SD卡状态
public static boolean hasSdcard(){
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case PHOTO_REQUEST_CAREMA:
if(resultCode==RESULT_OK){
/**
* 调用安卓系统进行图片裁剪问题
*/
Intent intent=new Intent("com.android.camera.action.CROP");
//设置intent的data和Type属性。
intent.setDataAndType(image_uri,"image/*");
intent.putExtra("scale",true);
intent.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
setPicture(ivPhotoshow,image_uri);
}
break;
case PHOTO_ALBUM:
if(resultCode==RESULT_OK){
album_uri=data.getData();
Intent intent=new Intent("com.android.camera.action.CROP");
intent.setDataAndType(album_uri,"image/*");
intent.putExtra("scale",true);
intent.putExtra(MediaStore.EXTRA_OUTPUT,album_uri);
setPicture(ivPhotoshow,album_uri);
// 启动裁剪
// startActivityForResult(intent, SHOW_PHOTO_ALBUM);
}
break;
//图片裁剪
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(this.getContentResolver()
.openInputStream(image_uri));
ivPhotoshow.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
}
}
private void setPicture(ImageView imageView,Uri uri) {
Bitmap bitmap1=null;
ivPhotoshow.setImageBitmap(bitmap1);
meMoryBitmap.recycleImageView(ivPhotoshow);
if(context!=null){
//获取图片大小
int targetW=imageView.getWidth();
int targetH=imageView.getHeight();
//Options,此类用于解码Bitmap时的各种参数控制,
BitmapFactory.Options bmpOptions=new BitmapFactory.Options();
//如果将inJustDecodeBounds这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。
// 这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。
//充分利用它,来避免大图片的溢出问题。
bmpOptions.inJustDecodeBounds=true;
try {
//BitmapFactory.decodeStream解决OOM内存用完了的情况
BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
int photoW=bmpOptions.outWidth;
int photoH=bmpOptions.outHeight;
int scaleFactor=Math.min(photoW/targetW,photoH/targetH);
bmpOptions.inJustDecodeBounds=false;
//Options中有个属性inSampleSize。我们可以充分利用它,实现缩放
bmpOptions.inSampleSize=scaleFactor;
int sizeFactor=calculateInSampleSize(bmpOptions,targetW,targetH);
Log.d(TAG,"sizeFactor"+sizeFactor+",scaleFactor"+scaleFactor);
/*节约内存 下面两个字段需要组合使用 */
bmpOptions.inPurgeable=true;
bmpOptions.inInputShareable = true;
//再次decode获取bitmap
Bitmap bitmap=BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,bmpOptions);
imageView.setImageBitmap(bitmap);
registerBean.setAvatar(String.valueOf(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
private int calculateInSampleSize(BitmapFactory.Options bmpOptions, int reqWidth, int reqHeight) {
final int height=bmpOptions.outHeight;
final int width=bmpOptions.outWidth;
int inSampleSize=1;
if(height>reqHeight||width>reqWidth){
final int halfheight=height/2;
final int halWidth=width/2;
while((halfheight/inSampleSize)>reqHeight&&(halWidth/inSampleSize)>reqWidth){
inSampleSize*=2;
}
}
return inSampleSize;
}
//图片上传,调用接口
private void uploadOk(File file) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.build();
//设置上传文件以及文件对应的MediaType类型
RequestBody requestBody = MultipartBody.create(MediaType.parse("image/jpeg"), file);
//MultipartBody文件上传
/**区别:
* addFormDataPart: 上传key:value形式
* addPart: 只包含value数据
*/
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)//设置文件上传类型
.addFormDataPart("key", "img")//文件在服务器中保存的文件夹路径
.addFormDataPart("file", file.getName(), requestBody)//包含文件名字和内容
.build();
Request request = new Request.Builder()
.url(你的图片上传url)
.header("Token",你的token)
.post(body)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("e","e"+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
//返回的数据,可用Gson解析
}
});
}
MeMoryBitmap
public class MeMoryBitmap {
public static MeMoryBitmap mInstance=null;
public MeMoryBitmap() {
}
public static MeMoryBitmap getmInstance() {
if(mInstance==null){
mInstance=new MeMoryBitmap();
}
return mInstance;
}
/**
* 网络获取俩,解析url获取图片
* @param path
* @return
* @throws IOException
*/
public static Bitmap getBitmap(String path) throws IOException {
try {
Log.d("url","bitmapurl000:"+path);
URL url = new URL(path);
//网络请求接口HttpURLConnection,可以实现简单的基于URL请求、响应功能。得到connection对象。
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
//设置请求方式
conn.setRequestMethod("GET");
判断得到响应码
if (conn.getResponseCode() == 200) {
得到响应流
InputStream inputStream = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
return bitmap;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 解决内存泄漏问题
* @param
*/
public void recycleImageView(ImageView ivPhotoshow) {
if(ivPhotoshow==null){return;}
if(ivPhotoshow instanceof ImageView){
Drawable drawable=ivPhotoshow.getDrawable();
//instanceof 是 Java 的保留关键字,它的作用是测试它左边的对象是否是它右边的类的实例
if(drawable instanceof BitmapDrawable){
Bitmap bmp=((BitmapDrawable) drawable).getBitmap();
if(bmp!=null&&!bmp.isRecycled()){
ivPhotoshow.setImageBitmap(null);
bmp.recycle();
}
}
}
}
/**
* 动态获取图片的缩放值
*
* @param options
* BitmapFactory.Options
* @param reqWidth
* 设定的Img控件宽度
* @param reqHeight
* 设定的Img控件高度
* @return inSampleSize
*/
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth)
{
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
{
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
文章来源:https://www.toymoban.com/news/detail-513822.html
到了这里,关于Android调用相机拍照,调用图库,上传图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!