Android camera 篇之拍照

本文是camera系列文章第一篇,预计三篇 :一 拍照;二 视频;三 自定义相机
相机功能是我们最常用的,属于andorid基础能力。本文讲述一下Android如何调用相机进行拍照。

废话不多说,直接上流程。

流程介绍

请求权限

开启相机

拍照并处理结果

先介绍一下请求码

private int takeCameraCodeOne = 1000; // 获取缩略图
private int takeCameraCodeTwo = 1001; // 获取全尺寸图
private int cameraCode = 10002; // 权限请求码

首先介绍申请权限

需要相机、读、写 三个权限
 
private String[] permissions = new String[]{"android.permission.CAMERA",
        "android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"};

申请权限并处理权限
/**
* 申请权限
*/
private void requestPermission() {
ActivityCompat.requestPermissions(this,permissions,cameraCode);
}

/**
 * 权限处理
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    /**
     * 权限处理
     */
    if (requestCode == cameraCode) {
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                requestPermission();
                return;
            }
        }
    //    openCameraOne();
        openCameraTwo();
    }
}

得到权限后开始唤醒相机,本文介绍两种拍照处理方式

先说第一种:拍照获取缩略图
/**
* 唤醒系统相机
*/
private void openCameraOne() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent,takeCameraCodeOne);
}
}

/**
* 获取拍照结果
* @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);
}
}
}
}
}

这种方式获取的图片,适用于小图标,存在像素低的缺点。

第二种 获取全尺寸照片

/**
* 唤醒相机
*/
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的行为更变 就是获取设备文件使用provider 的问题

/**
* 获取拍照结果
* @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);

        }
    }
}

这里的全尺寸图的,像素高占内存也大,所以我做了压缩处理;

/**
* 获取路径指定位置 这里是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;
}

/**
 * 计算比例
 * @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();
    }
}

然后最后还有一点说明 将照片保存到手机相册

/**
* 加入手机相册
* @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 拍照
  • 流程
  • 请求权限
  • 开启相机
  • 拍照并处理结果

*/

public class OpenCameraActivity extends AppCompatActivity {

private int takeCameraCodeOne = 1000; // 获取缩略图
private int takeCameraCodeTwo = 1001; // 获取全尺寸图
private int cameraCode = 10002;  // 权限请求码
/**
 * 所需权限数组 相机 读 写
 */
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();
    });
}

/**
 * 申请权限
 */
private void requestPermission() {
    ActivityCompat.requestPermissions(this,permissions,cameraCode);
}

/**
 * 权限处理
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    /**
     * 权限处理
     */
    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;
}

/**
 * 唤醒相机
 */
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);
    }
}

/**
 * 获取拍照结果
 * @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;
}

/**
 * 计算比例
 * @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();
    }
}

/**
 * 加入手机相册
 * @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);
}


/**
 * 唤醒系统相机
 */
private void openCameraOne() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent,takeCameraCodeOne);
    }
}

}
本文完。

你可能感兴趣的:(Android camera 篇之拍照)