当前位置:主页 > 查看内容

Android记录:运用系统相机拍照并获取原图+原图压缩+上传数据

发布时间:2021-09-09 00:00| 位朋友查看

简介:项目中一般用于头像更换、单图拍摄取图等 目录 一、系统相机 1.1 获取权限 1.2 Android6.0或者更高版本需要动态获取权限 1.3 打开相机 1.4 Android 7.0或更高版本相机打开的时候闪退问题 二、获取原图 三、原图压缩 1.1 现在获取的图片在部分手机会出现旋转……

项目中一般用于头像更换、单图拍摄取图等

一、系统相机

1.先获取权限
2.再利用Intent 打开系统相机

1.1 获取权限

	// 拍摄照片权限
    <uses-permission android:name="android.permission.CAMERA"/>

1.2 Android6.0或者更高版本需要动态获取权限

先把所需要的的权限用数组装起来(需要其他权限还可以在里面添加)

	private static String[] PERMISSIONS_STORAGE = {
               "android.permission.CAMERA"};
   public void verifyStoragePermissions(Activity activity) {
  		//然后通过其中的一个函数来申请
       int checkSelfPermission = ActivityCompat.checkSelfPermission(activity, PERMISSIONS_STORAGE[0]);
       if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
           // 没有写的权限,去申请写的权限,会弹出对话框
           ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
       }
   }

1.3 打开相机

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);

1.4 Android 7.0或更高版本相机打开的时候闪退问题

需要打开防止内存泄露工具 StrictMode

  private void initPhoto() {
        // android 7.0系统解决拍照的问题
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();
    }

上面最好写在onCreate()里面

二、获取原图

1.打开相机的时候创建绝对路径
2.根据绝对路径获取URI,并把URI通过Intent存起来
3.最后根据startActivityForResult在onActivityResult中返回中获取原图file

    /**
    * 本地绝对路径添加文件夹的名字
    */
   private final String IMAGE_FILE_LOCATION = "image";
   
    /**
    * 图片名字
    */
   private String localFileName = "";
   
       /**
    * 图片file
    */
   private File file;
   
   /**
   *打开相机
   */
   private void openCream() {
       localFileName = System.currentTimeMillis() + "" + ".jpg";
       //先验证手机是否有sdcard
       String status = Environment.getExternalStorageState();
       if (status.equals(Environment.MEDIA_MOUNTED)) {
           try {
               File dir = new File(Environment.getExternalStorageDirectory() + "/" + IMAGE_FILE_LOCATION);
               if (!dir.exists()) {
                   dir.mkdirs();
               }
               Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
               File file = new File(dir,localFileName );
               Uri uri = Uri.fromFile(file);
               intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
               intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
               startActivityForResult(intent, 1);
           } catch (ActivityNotFoundException e) {
               Toast.makeText(getActivity(), "没有找到储存目录", Toast.LENGTH_LONG).show();
           }
       } else {
           Toast.makeText(getActivity(), "没有储存卡", Toast.LENGTH_LONG).show();
       }
   }
   
 
 @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
       if (resultCode == Activity.RESULT_OK) {
           if (requestCode == 1) {
               file = new File(Environment.getExternalStorageDirectory()
                       + "/" + IMAGE_FILE_LOCATION + "/" + localFileName);
                       
                     /**
                     *获取到压缩图(大概为300k左右)URI保存到本地并显示在imgview中
                     */
                        setBackground(saveBitmap(rotateBitmap(getImage(file.getPath()), readPictureDegree(file.getPath()))));
           }

       }
   }

三、原图压缩

原理:重新定义好bitmap的高(Width)和宽(Hight)

/**
     * 图片按比例大小压缩方法
     *
     * @param srcPath (根据路径获取图片并压缩)
     * @return Bitmap
     */
     
    public static Bitmap getImage(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        // 此时返回bm为空
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 这里设置高度为720f
        float hh = 720f;
        // 这里设置宽度为1024f
        float ww = 1024f;
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        // be=1表示不缩放
        int 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了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        // 压缩好比例大小后再进行质量压缩
        return compressImage(bitmap);
    }

1.1 现在获取的图片在部分手机会出现旋转了90°,解决办法

1.获取图片的方向
2.根据获取到的图片方向进行矫正

/**
    * 图片正常方向
    *
    * @param bitmap  图片bitmap
    * @param degrees 矫正方向
    * @return Bitmap
    */
    
   public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
       if (degrees == 0 || null == bitmap) {
           return bitmap;
       }
       Matrix matrix = new Matrix();
       matrix.setRotate(degrees, bitmap.getWidth() >> 1, bitmap.getHeight() >> 1);
       Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
       bitmap.recycle();
       return bmp;
   }
   
/**
    * 图片旋转
    *
    * @param path 图片路径
    * @return int
    */
    
   public static int readPictureDegree(String path) {
       int degree = 0;
       try {
           ExifInterface exifInterface = new ExifInterface(path);
           int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
           switch (orientation) {
               case ExifInterface.ORIENTATION_ROTATE_90:
                   degree = 90;
                   break;
               case ExifInterface.ORIENTATION_ROTATE_180:
                   degree = 180;
                   break;
               case ExifInterface.ORIENTATION_ROTATE_270:
                   degree = 270;
                   break;
               default:
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
       return degree;

   }

1.2 压缩图片保存

根据URI利用文件流写进去

/**
    * 保存图片
    *
    * @param bm 资源(这里也可以再次进行压缩)
    * @return uri
    */
   private Uri saveBitmap(Bitmap bm) {
       try {
           FileOutputStream fos = new FileOutputStream(file);
           bm.compress(Bitmap.CompressFormat.JPEG, 100, fos);
           fos.flush();
           fos.close();
           return Uri.fromFile(file);
       } catch (IOException e) {
           e.printStackTrace();
           return null;
       }
   }

1.3 图片显示

这里显示在一个imgview中

 /**
     * 设置图片背景
     *
     * @param uri URi
     */
    private void setBackground(Uri uri) {
        InputStream inputStream;
        Drawable drawable = null;
        try {
            Log.i("图片回调", " uri " + uri);
            inputStream = getActivity().getContentResolver().openInputStream(uri);
            drawable = Drawable.createFromStream(inputStream, "dataString");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (drawable != null) {
            imgview.setBackground(drawable);
            imgview.setVisibility(View.VISIBLE);
            Log.d("图片回调", "set ok");
        } else {
            imgview.setVisibility(View.GONE);
            Log.e("图片回调", "setBackground error");
        }
    }

四、图片上传

根据获取到的file,利用RequestBody

       MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
            if (file.exists()) {
                RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                builder.addFormDataPart("file", file.getName(), imageBody);  
            }
            RequestBody requestBody = builder.build();

multipart/form-data :这个要看后台是需要什么形式传,图片或许是 image/*

;原文链接:https://blog.csdn.net/weixin_44357587/article/details/115937715
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:教你在Unity 2020接Facebook SDK(Android平台) 下一篇:没有了

推荐图文


随机推荐