android调用系统拍照那些事

Posted F_YuXiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android调用系统拍照那些事相关的知识,希望对你有一定的参考价值。

小时候都知道每天写日记是个好习惯,慢慢发现自己忘记了这些习惯,好久没有给这干枯的博客添加一点新意了,这回也冒出个小芽来刷新一下博客。

今天写的一点也不复杂,就是回顾一些老的知识而已,也算是记一个笔记,好了闲话不多说了,开始今天的主题吧。

关于拍照,这里不是自己实现拍照,是调用系统拍照,很简单的,可是有些时候我也遇到一个问题,就是我没有主动压缩,系统却自动帮我压缩了,可是我需要这些高清的图片,解决方式网上也有说,但是我做的是自己的笔记,所以也不在乎赘余,最起码我是经过验证后,才写我笔记的。

下面是系统默认压缩图片的调用方式

1     private static final int TAKE_PICTURE = 0x000001;
2     public void photo() {
3         Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
4         startActivityForResult(openCameraIntent, TAKE_PICTURE);
5     }
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    switch (requestCode) {
       case TAKE_PICTURE:
      if (&& resultCode == RESULT_OK) {
            String fileName = String.valueOf(System.currentTimeMillis());
       Bitmap bm = null;
             ContentResolver resolver = getContentResolver();
        if (originalUri == null) {
                    bm = (Bitmap) intent.getExtras().get("data");//小米5测试发现好像走这里,华为G521 android4.3老机器也走这里
                } else {
                    try {
                        bm = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));
                        LogUtil.e(TAG, "originalBitmap photo width=" + bm.getWidth());
                        bm = comp(bm);//这里是压缩至于压缩方法,就放下面提供了
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }        
          //剩下就自己操作bitmap了比如下面的保存
FileUtils.saveBitmap(bm, fileName);
          //........
  }
    break;
  this.mLoginHelper.onActivityResult(requestCode, resultCode, intent);
}

上面的是常用的调用方式,缺点就是图片会被系统自己压缩。

也不兜圈子,下面的方法就是保存原图的方式。

 1     private static final int TAKE_PICTURE = 0x000001;
 2     private String fileName;
 3 
 4     public void photo() {
 5         Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 6         fileName = String.valueOf(System.currentTimeMillis());
 7         File photoFile = FileUtils.createPic(fileName);
 8         openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
 9         startActivityForResult(openCameraIntent, TAKE_PICTURE);
10     }

返回调用

 1 @Override
 2     protected void onActivityResult(int requestCode, int resultCode, Intent intent) {36         switch (requestCode) {
37         case TAKE_PICTURE:
38             if (Bimp.tempSelectBitmap.size() < 3 && resultCode == RESULT_OK) {
44                 Uri originalUri = null;
45                 File f=FileUtils.getPic(fileName);
46                 try {
47                     originalUri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(),f.getAbsolutePath(), null, null));
48                 } catch (FileNotFoundException e) {
49                     e.printStackTrace();
50                 }
52                 Bitmap bm = null;
53                 ContentResolver resolver = getContentResolver();
56                 if (originalUri == null) {
58                     bm = (Bitmap) intent.getExtras().get("data");
59                 } else {
60                     try {
61                         bm = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));
63                         LogUtil.e(TAG, "originalBitmap photo width=" + bm.getWidth());
65                         bm = comp(bm);
66                     } catch (FileNotFoundException e) {
67                         e.printStackTrace();
68                     }
69 
70                 }
71                 FileUtils.saveBitmap(bm, fileName);
72 
73                //继续操作78 
79             }
80             break;
81         }
82         this.mLoginHelper.onActivityResult(requestCode, resultCode, intent);
83     }

 下面是保存方法:

public static void saveBitmap(Bitmap bm, String picName) {
        try {
            if (!isFileExist("")) {
                File tempf = createSDDir("");
            }
            File f = new File(SDPATH, picName + ".JPEG");
            if (f.exists()) {
                f.delete();
            }
            FileOutputStream out = new FileOutputStream(f);
            bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

下面是压缩方法:

private Bitmap comp(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        if (baos.toByteArray().length / 1024 > 1024) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 1000f;// 这里设置高度为800f
        float ww = 1000f;// 这里设置宽度为480f
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
    }

    private 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,大于继续压缩
        while (baos.toByteArray().length / 1024 > 2048) { // 循环判断如果压缩后图片是否大于1024kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

 

以上是关于android调用系统拍照那些事的主要内容,如果未能解决你的问题,请参考以下文章

调用 android 系统拍照结合 android-crop 裁剪图片

关于Android架构那些事

android固定位置拍照,Android调用系统相机拍照并保存到指定位置

Android WebView 调用系统拍照和相册

从片段中的相机拍照

Android7.0调用系统相机拍照读取系统相册照片+CropImageView剪裁照片