本文是camera系列文章第一篇,預(yù)計(jì)三篇 :一 拍照龄砰;二 視頻;三 自定義相機(jī)
相機(jī)功能是我們最常用的讨衣,屬于andorid基礎(chǔ)能力换棚。本文講述一下Android如何調(diào)用相機(jī)進(jìn)行拍照。
廢話不多說反镇,直接上流程固蚤。
流程介紹
請(qǐng)求權(quán)限
開啟相機(jī)
拍照并處理結(jié)果
先介紹一下請(qǐng)求碼
private int takeCameraCodeOne = 1000; // 獲取縮略圖
private int takeCameraCodeTwo = 1001; // 獲取全尺寸圖
private int cameraCode = 10002; // 權(quán)限請(qǐng)求碼
首先介紹申請(qǐng)權(quán)限
需要相機(jī)、讀歹茶、寫 三個(gè)權(quán)限
private String[] permissions = new String[]{"android.permission.CAMERA",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"};
申請(qǐng)權(quán)限并處理權(quán)限
/**
* 申請(qǐng)權(quán)限
*/
private void requestPermission() {
ActivityCompat.requestPermissions(this,permissions,cameraCode);
}
/**
* 權(quán)限處理
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
/**
* 權(quán)限處理
*/
if (requestCode == cameraCode) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
requestPermission();
return;
}
}
// openCameraOne();
openCameraTwo();
}
}
得到權(quán)限后開始喚醒相機(jī)夕玩,本文介紹兩種拍照處理方式
先說第一種:拍照獲取縮略圖
/**
* 喚醒系統(tǒng)相機(jī)
*/
private void openCameraOne() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent,takeCameraCodeOne);
}
}
/**
* 獲取拍照結(jié)果
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == takeCameraCodeOne) {
if (data != null && data.getExtras() != null) {
Bundle bundle = data.getExtras();
Bitmap bm = (Bitmap) bundle.get("data");
if (bm != null) {
camera_img.setImageBitmap(bm);
}
}
}
}
}
這種方式獲取的圖片你弦,適用于小圖標(biāo),存在像素低的缺點(diǎn)燎孟。
第二種 獲取全尺寸照片
/**
* 喚醒相機(jī)
*/
private void openCameraTwo() {
Uri fileUri;
out = new File(getFileName());
if (Build.VERSION.SDK_INT >= 24){
fileUri = FileProvider.getUriForFile(this,getPackageName()+".provider", out);
}else {
fileUri = Uri.fromFile(out);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
if (Build.VERSION.SDK_INT >= 24) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, takeCameraCodeTwo);
}
}
這里兼容了Android 7的行為更變 就是獲取設(shè)備文件使用provider 的問題
/**
* 獲取拍照結(jié)果
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == takeCameraCodeTwo){
Bitmap bm = getBitMap(out.getAbsolutePath(), getFileName());
camera_img.setImageBitmap(bm);
}
}
}
這里的全尺寸圖的禽作,像素高占內(nèi)存也大,所以我做了壓縮處理揩页;
/**
* 獲取路徑指定位置 這里是DCIM位置 也可指定其他位置
* @return
*/
public String getFileName() {
String fileName = null;
long currentTimeMillis = System.currentTimeMillis();
String pathName = Environment.getExternalStorageDirectory() + "/DCIM/";
File file = new File(pathName);
file.mkdirs();
fileName = pathName + currentTimeMillis + ".jpg";
return fileName;
}
/**
* 獲取圖片
* @param path
* @param fileName
* @return
*/
private Bitmap getBitMap(String path, String fileName) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path,options);
options.inSampleSize = calculateInSampleSize(options,2180,2180);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
compressBmpToFile(bitmap,new File(fileName));
return bitmap;
}
/**
* 計(jì)算比例
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
public 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 heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
/**
* 壓縮圖片 并保存到指定文件位置
* @param bmp
* @param file
*/
String imgpath ;
public void compressBmpToFile(Bitmap bmp,File file){
if (file != null) {
imgpath = file.getAbsolutePath();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 80;
if (bmp == null) {
return;
}
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
while (baos.toByteArray().length / 1024 > 500) {
baos.reset();
options -= 10;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
然后最后還有一點(diǎn)說明 將照片保存到手機(jī)相冊(cè)
/**
* 加入手機(jī)相冊(cè)
* @param path 圖片路徑
*/
public void addGallery(String path){
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(path);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
好旷偿,兩種拍照方式介紹完畢了。完整代碼隨后加上
/**
- camera 拍照
- 流程
- 請(qǐng)求權(quán)限
- 開啟相機(jī)
- 拍照并處理結(jié)果
*/
public class OpenCameraActivity extends AppCompatActivity {
private int takeCameraCodeOne = 1000; // 獲取縮略圖
private int takeCameraCodeTwo = 1001; // 獲取全尺寸圖
private int cameraCode = 10002; // 權(quán)限請(qǐng)求碼
/**
* 所需權(quán)限數(shù)組 相機(jī) 讀 寫
*/
private String[] permissions = new String[]{"android.permission.CAMERA",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"};
private ImageView camera_img;
private File out;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
camera_img = findViewById(R.id.camera_img);
findViewById(R.id.open_camera).setOnClickListener(v -> {
requestPermission();
});
}
/**
* 申請(qǐng)權(quán)限
*/
private void requestPermission() {
ActivityCompat.requestPermissions(this,permissions,cameraCode);
}
/**
* 權(quán)限處理
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
/**
* 權(quán)限處理
*/
if (requestCode == cameraCode) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
requestPermission();
return;
}
}
// openCameraOne();
openCameraTwo();
}
}
/**
* 獲取路徑指定位置 這里是DCIM位置 也可指定其他位置
* @return
*/
public String getFileName() {
String fileName = null;
long currentTimeMillis = System.currentTimeMillis();
String pathName = Environment.getExternalStorageDirectory() + "/DCIM/";
File file = new File(pathName);
file.mkdirs();
fileName = pathName + currentTimeMillis + ".jpg";
return fileName;
}
/**
* 喚醒相機(jī)
*/
private void openCameraTwo() {
Uri fileUri;
out = new File(getFileName());
if (Build.VERSION.SDK_INT >= 24){
fileUri = FileProvider.getUriForFile(this,getPackageName()+".provider", out);
}else {
fileUri = Uri.fromFile(out);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
if (Build.VERSION.SDK_INT >= 24) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, takeCameraCodeTwo);
}
}
/**
* 獲取拍照結(jié)果
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == takeCameraCodeOne) {
if (data != null && data.getExtras() != null) {
Bundle bundle = data.getExtras();
Bitmap bm = (Bitmap) bundle.get("data");
if (bm != null) {
camera_img.setImageBitmap(bm);
}
}
}else if (requestCode == takeCameraCodeTwo){
Bitmap bm = getBitMap(out.getAbsolutePath(), getFileName());
camera_img.setImageBitmap(bm);
if (!TextUtils.isEmpty(imgpath)) {
addGallery(imgpath);
}
}
}
}
/**
* 獲取圖片
* @param path
* @param fileName
* @return
*/
private Bitmap getBitMap(String path, String fileName) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path,options);
options.inSampleSize = calculateInSampleSize(options,2180,2180);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
compressBmpToFile(bitmap,new File(fileName));
return bitmap;
}
/**
* 計(jì)算比例
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
public 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 heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
/**
* 壓縮圖片 并保存到指定文件位置
* @param bmp
* @param file
*/
String imgpath ;
public void compressBmpToFile(Bitmap bmp,File file){
if (file != null) {
imgpath = file.getAbsolutePath();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 80;
if (bmp == null) {
return;
}
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
while (baos.toByteArray().length / 1024 > 500) {
baos.reset();
options -= 10;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加入手機(jī)相冊(cè)
* @param path 圖片路徑
*/
public void addGallery(String path){
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(path);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
/**
* 喚醒系統(tǒng)相機(jī)
*/
private void openCameraOne() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent,takeCameraCodeOne);
}
}
}
本文完碍沐。