//随便定义的静态值 调用相机的时候用的 在onActivityResult里面和requestCode 值相对应
private static final int REQUEST_TAKE_PHOTO_CODE = 123;
1.首先判断有没有开启权限
if (!checkPermission()) { //没有或没有全部授权
requestPermissions(); //请求权限
}
else {
//如果开启了 直接调用相机
takePhoto();//拍照逻辑
}
//检查权限
private boolean checkPermission() {
//是否有权限
boolean haveCameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
boolean haveWritePermission = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
return haveCameraPermission && haveWritePermission;
}
// 请求所需权限
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestPermissions() {
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE);
}
//开启权限返回
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSION_CODE:
boolean allowAllPermission = false;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {//被拒绝授权
allowAllPermission = false;
break;
}
allowAllPermission = true;
}
if (allowAllPermission) {
takePhoto();//开始拍照或从相册选取照片
} else {
Toast.makeText(this, "该功能需要授权方可使用", Toast.LENGTH_SHORT).show();
}
break;
}
}
//调用相机的方法
private void takePhoto() {
// 步骤一:创建存储照片的文件
String path = getFilesDir() + File.separator + "images" + File.separator;
File file = new File(path, "test.jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//步骤二:Android 7.0及以上获取文件 Uri
//com.rk.myfeaturesapp是自己App的包名fileprovider是死值
mUri = FileProvider.getUriForFile(CamearActivity.this, "com.rk.myfeaturesapp.fileprovider", file);
} else {
//步骤三:获取文件Uri
mUri = Uri.fromFile(file);
}
//步骤四:调取系统拍照
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
startActivityForResult(intent,REQUEST_TAKE_PHOTO_CODE);
}
//返回的参数
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_TAKE_PHOTO_CODE) {//获取系统照片上传
Bitmap bm = null;
try {
bm = getBitmapFormUri(mUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
imageView.setImageBitmap(bm);
}
}
//返回的照片进行压缩
public Bitmap getBitmapFormUri(Uri uri) throws FileNotFoundException, IOException {
InputStream input = getContentResolver().openInputStream(uri);
//这一段代码是不加载文件到内存中也得到bitmap的真是宽高,主要是设置inJustDecodeBounds为true
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;//不加载到内存
onlyBoundsOptions.inDither = true;//optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.RGB_565;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
int originalWidth = onlyBoundsOptions.outWidth;
int originalHeight = onlyBoundsOptions.outHeight;
if ((originalWidth == -1) || (originalHeight == -1))
return null;
//图片分辨率以480x800为标准
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (originalWidth / ww);
} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (originalHeight / hh);
}
if (be <= 0)
be = 1;
//比例压缩
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = be;//设置缩放比例
bitmapOptions.inDither = true;
bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
input = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return compressImage(bitmap);//再进行质量压缩
}
//进行二次压缩
public Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
//第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options,把压缩后的数据存放到baos中
options -= 10;//每次都减少10
if (options<=0)
break;
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
//在Androidmanifest进行配置
在<application>里面进行配置
<provider
android:name="androidx.core.content.FileProvider"
//android:authorities="com.rk.myfeaturesapp.fileprovider"和上面的保持一致
android:authorities="com.rk.myfeaturesapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
//tools:replace="android:resource"是调用手机相机录屏的时候用的
tools:replace="android:resource"
android:name="android.support.FILE_PROVIDER_PATHS"
//@xml/file_paths 在res下面创建个文件夹在xml里面创建一个xml名字为file_paths
android:resource="@xml/file_paths" />
</provider>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--files-path 相当于 getFilesDir()-->
<files-path name="my_images" path="images"/>
<!--cache-path 相当于 getCacheDir()-->
<cache-path name="lalala" path="cache_image"/>
<!--external-path 相当于 Environment.getExternalStorageDirectory()-->
<external-path name="hahaha" path="comeOn"/>
<!--external-files-path 相当于 getExternalFilesDir("") -->
<external-files-path name="paly" path="freeSoft"/>
<!--external-cache-path 相当于 getExternalCacheDir() -->
<external-cache-path name="lei" path="."/>
//这一行代码的作用是在调用相机进行录屏的时候可以获取到SD卡的视频
<root-path path="" name="camera_photos" />
...
</paths>
android调用相机保存图片失败 android调用相机返回图片地址
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Phaser将当前运行场景保存为图片
将当前Phaser游戏运行场景保存为图片
搜索引擎 模拟点击 -
Delphi10.4 Android调用相机返回图片调试
Delphi XE10调用相机返回图片调试使用Delphi封装的“Standard Action”这些标准操作,可以非常方便我们调用Android系统功能。
Delphi Android Camera Standard Action