Android 解决部分手机拍照后获取的图片被旋转的问题

来源:互联网 发布:hg8245超级密码端口23 编辑:程序博客网 时间:2024/05/01 13:29

最近又被测试MM找茬了,调用Android系统拍照功能后,三星手机拍摄后的照片被旋转了90度,横着拍给你变成竖的,竖的拍给你变成横的。。。其它品牌的手机都是正常的,就三星出现这个怪事。

在Android适配上,我原来一直以为国内的小米手机够奇葩了,结果还有更奇葩的!你说你没事旋转照片干啥,实在是猜不透其居心何在,纯粹是在给开发者制造麻烦啊!

解决办法是获取到拍照后照片被旋转的角度,再旋转回去就好了。


具体思路:

1、首先在调用拍照方法时,保存拍照后的相片原图,得到原图路径,(PhotoBitmapUtils是我自己写的一个工具类)

    String fileName = "";    /**     * 启动相机拍照     */    private void addBitmapShoots() {        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        // 设置图片要保存的 根路径+文件名        fileName = PhotoBitmapUtils.getPhotoFileName(getContext());        File file = new File(fileName);        if (!file.exists()) {            try {                file.createNewFile();            } catch (IOException e) {                e.printStackTrace();            }        }        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));        startActivityForResult(intent, OPEN_CAMERA);    }

2、在获取相机返回的回调方法onActivityResult()中,修复被旋转的图片并取得修复后的图片路径,有了这个路径后就可以展示出来了

    @Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        // 获取相机拍照返回        if (resultCode == Activity.RESULT_OK && requestCode == OPEN_CAMERA) {            // 得到修复后的照片路径            String filepath = PhotoBitmapUtils.amendRotatePhoto(fileName, getContext());        }    }

PhotoBitmapUtils类:

/** * 集合一些图片工具 * * Created by zhuwentao on 2016-07-22. */public class PhotoBitmapUtils {    /**     * 存放拍摄图片的文件夹     */    private static final String FILES_NAME = "/MyPhoto";    /**     * 获取的时间格式     */    public static final String TIME_STYLE = "yyyyMMddHHmmss";    /**     * 图片种类     */    public static final String IMAGE_TYPE = ".png";    // 防止实例化    private PhotoBitmapUtils() {    }    /**     * 获取手机可存储路径     *     * @param context 上下文     * @return 手机可存储路径     */    private static String getPhoneRootPath(Context context) {        // 是否有SD卡        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)                || !Environment.isExternalStorageRemovable()) {            // 获取SD卡根目录            return context.getExternalCacheDir().getPath();        } else {            // 获取apk包下的缓存路径            return context.getCacheDir().getPath();        }    }    /**     * 使用当前系统时间作为上传图片的名称     *     * @return 存储的根路径+图片名称     */    public static String getPhotoFileName(Context context) {        File file = new File(getPhoneRootPath(context) + FILES_NAME);        // 判断文件是否已经存在,不存在则创建        if (!file.exists()) {            file.mkdirs();        }        // 设置图片文件名称        SimpleDateFormat format = new SimpleDateFormat(TIME_STYLE, Locale.getDefault());        Date date = new Date(System.currentTimeMillis());        String time = format.format(date);        String photoName = "/" + time + IMAGE_TYPE;        return file + photoName;    }    /**     * 保存Bitmap图片在SD卡中     * 如果没有SD卡则存在手机中     *     * @param mbitmap 需要保存的Bitmap图片     * @return 保存成功时返回图片的路径,失败时返回null     */    public static String savePhotoToSD(Bitmap mbitmap, Context context) {        FileOutputStream outStream = null;        String fileName = getPhotoFileName(context);        try {            outStream = new FileOutputStream(fileName);            // 把数据写入文件,100表示不压缩            mbitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);            return fileName;        } catch (Exception e) {            e.printStackTrace();            return null;        } finally {            try {                if (outStream != null) {                    // 记得要关闭流!                    outStream.close();                }                if (mbitmap != null) {                    mbitmap.recycle();                }            } catch (Exception e) {                e.printStackTrace();            }        }    }    /**     * 把原图按1/10的比例压缩     *     * @param path 原图的路径     * @return 压缩后的图片     */    public static Bitmap getCompressPhoto(String path) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = false;        options.inSampleSize = 10;  // 图片的大小设置为原来的十分之一        Bitmap bmp = BitmapFactory.decodeFile(path, options);        options = null;        return bmp;    }    /**     * 处理旋转后的图片     * @param originpath 原图路径     * @param context 上下文     * @return 返回修复完毕后的图片路径     */    public static String amendRotatePhoto(String originpath, Context context) {        // 取得图片旋转角度        int angle = readPictureDegree(originpath);        // 把原图压缩后得到Bitmap对象        Bitmap bmp = getCompressPhoto(originpath);;        // 修复图片被旋转的角度        Bitmap bitmap = rotaingImageView(angle, bmp);        // 保存修复后的图片并返回保存后的图片路径        return savePhotoToSD(bitmap, context);    }    /**     * 读取照片旋转角度     *     * @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 rotaingImageView(int angle, Bitmap bitmap) {        Bitmap returnBm = null;        // 根据旋转角度,生成旋转矩阵        Matrix matrix = new Matrix();        matrix.postRotate(angle);        try {            // 将原始图片按照旋转矩阵进行旋转,并得到新的图片            returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);        } catch (OutOfMemoryError e) {        }        if (returnBm == null) {            returnBm = bitmap;        }        if (bitmap != returnBm) {            bitmap.recycle();        }        return returnBm;    }}

在调用修复图片角度方法的时候需要注意,现在的手机像素越来越大,拍完后一张照片有近10M,所以我们需要对图片进行压缩处理。不然在保存图片时会等待挺久的,屏幕会黑一会。

参考文档1

参考文档2

0 0
原创粉丝点击