Android调用手机相机拍照,保存图片会出现2张解决办法。

最近项目中使用系统相机拍照,保存图片,发现一些问题。

(1)小米手机拍照图片会旋转

  读取图片旋转角度,然后再旋转回去。

/**
 * 读取照片旋转角度
 *
 * @param path 照片路径
 * @return 角度
 */
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;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return degree;
}
/**
 * 旋转图片
 *
 * @param angle  被旋转角度
 * @param bitmap 图片对象
 * @return 旋转后的图片
 */
public static Bitmap rotatingImageView(int angle, Bitmap bitmap) {
    Bitmap returnBm = null;
    // 根据旋转角度,生成旋转矩阵
    Matrix matrix = new Matrix();
    matrix.postScale(-1,1);
    matrix.postRotate(angle);
    try {
        // 将原始图片按照旋转矩阵进行旋转,并得到新的图片
        returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    } catch (OutOfMemoryError e) {
        LogUtil.e(e.getMessage());
    } catch (Exception e) {
        LogUtil.e(e.getMessage());
    }
    if (returnBm == null) {
        returnBm = bitmap;
    }
    if (bitmap != returnBm) {
        bitmap.recycle();
    }
    return returnBm;
}

(2)读取图片是否为 .gif 图片

   使用BitmapFactory.Options,能更准确的获取图片格式,
   判断地址末尾 .gif 有时候会不准确(不推荐)

//区分是不是.gif
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
if ("image/gif".equals(options.outMimeType)) {
    imgPath = EditPhotSDCardUtil.getPictureDir() + pathName + "~";
} else {
    imgPath = EditPhotSDCardUtil.getPictureDir() + pathName + "-";
}

(3)上传图片到服务器,防止图片会被删除地址无效

  上传服务器,一般使用地址,但是用户手动删除图片后,地址是无效的。为了防止地址无效,可以对需要上传图片地址做保存,但又希望系统读取不到,可以对保存地址进行修改。

String SDCardRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
String imageCacheUrl = SDCardRoot + "APP_NAME" + File.separator;
File file = new File(imageCacheUrl);
if (!file.exists()) {
    file.mkdirs();  //如果不存在则创建
}
//区分 .gif,为了展示不同UI
if ("image/gif".equals(options.outMimeType)) {
    imgPath = imageCacheUrl + "文件名"+ "~";
} else {
    imgPath = imageCacheUrl + "文件名" + "-";
}

(4)调用系统相机,拍照后保存图片,会出现2张,而且只能读取到一张。

  读取图片地址api

final String[] IMAGE_PROJECTION = {
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media.DISPLAY_NAME,
                MediaStore.Images.Media.DATE_ADDED,
                MediaStore.Images.Media._ID,
                MediaStore.Images.Media.MINI_THUMB_MAGIC,
                MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
//读取相册图片地址
Cursor mCursor = mContentResolver.query(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        IMAGE_PROJECTION,
                        null,
                        null,
                        IMAGE_PROJECTION[2] + " DESC");

第一个问题,为什么会出现2张。

  我们可以去系统相册查看两张图片,会发现两张图片的地址是不一样的,而且两张图片的大小也不同。
出现2张的原因是:
 (1)调用系统相机,拍照完成我们会生成一个保存地址,而这个地址是: /storage/android/data/包名/Picture/ ,这张是我们保存的拍照图片。
 (2)相同的一张图片在哪?这个地址是:/storage/Pictures/ ,这张图片是系统复制的App目录下Pictures中的图片。

  所以就会出现在系统相册两张图片,但两张图片大小不一致,地址不同。

第二个问题,为什么只能读取到一张,是哪一张?

  调用系统api,只能读取到一张,是系统复制的那张,也就是 /storage/Pictures/ 目录下的这张,但是/storage/android/data/包名/Picture/ 目录下的没有读取到。

解决办法

  知道了问题,就有解决办法,可分为三种方法:
 (1)第一种方法:
     保存图片的时候,修改下地址(可参照标题 3 ,这样让系统无法识别出这张图片),结果就是,我读取不到,系统也别想读取不到,在系统相册里也就看不到这张图片。

 (2)第二种方法:
     因为api无法读取到,那我们就直接再读取/storage/android/data/包名/Picture/ 下的文件,把图片一块加入到同一个集合中用于展示,这样所有的图片都有了,但是系统相册中还是有两张图片,为解决这个问题。

 (3)第三种方法:()
     在我们保存图片的时候,直接保存到 /storage/Pictures/ 这个目录下,也不用系统帮我们复制了,这样就只会出现一张,而且我们也能调用api直接读取到,两个问题全都解决了,完美!

//不要这样保存 
//File storageDir = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);~~
//保存图片的时候,直接保存到/storage/Pictures/  
File storageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Pictures");



(如果以上有错误或者有更优美的方式,感谢指出并改之,与君共勉)
这是我项目中出现的问题,希望能够帮助到你,Thanks,Bye!

你可能感兴趣的:(Android调用手机相机拍照,保存图片会出现2张解决办法。)