第八例:android相机及本地选择、裁减、压缩图片

一、主要的几个压缩方式

/**
     * 保存图片时压缩
     *
     * @param bmp
     * @param file
     */
    public static void compressBmpToFile(Bitmap bmp, File file) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int options = 80;
        bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
        while (baos.toByteArray().length / 1024 > 1000) {
            baos.reset();
            options -= 1;
            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 srcPath
     * @param hh
     * @param ww
     * @return
     */
    private Bitmap compressImageFromFile(String srcPath, float hh, float ww) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;//只读边,不读内容
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        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;//设置采样率

        newOpts.inPreferredConfig = Bitmap.Config.ARGB_8888;//该模式是默认的,可不设
        newOpts.inPurgeable = true;// 同时设置才会有效
        newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收

        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
//      return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩
        //其实是无效的,大家尽管尝试
        return bitmap;
    }

二、相机的使用

//弹出选择框
    protected void createSelectImageDialog() {
        CharSequence[] items = {"相册", "照相机"};
        new AlertDialog.Builder(this).setTitle("选择图片来源").setItems(items,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == SELECT_PICTURE) {
                            Intent intent = new Intent();
                            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                                intent.setAction(Intent.ACTION_GET_CONTENT);
                            } else {
                                intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
                                intent.addCategory(Intent.CATEGORY_OPENABLE);
                            }
                            intent.setType("image/*");
                            startActivityForResult(Intent.createChooser(intent, "选择图片"),
                                    CONSULT_DOC_PICTURE);
                        } else {
                            String status = Environment.getExternalStorageState();
                            if (status.equals(Environment.MEDIA_MOUNTED)) {//判断是否有SD卡
                                doTakePhoto();
                            } else {
                                showToast("没有SD卡");
                            }

                        }
                    }
                }).create().show();
    }

    /**
     * 拍照获取图片
     */
    protected void doTakePhoto() {
        try {
            // Launch camera to take photo for selected contact
            PHOTO_DIR.mkdirs();// 创建照片的存储目录
            mCurrentPhotoFile = new File(PHOTO_DIR, getPhotoFileName());// 给新照的照片文件命名
            final Intent intent = getTakePickIntent(mCurrentPhotoFile);
            startActivityForResult(intent, CONSULT_DOC_CAMERA);
        } catch (ActivityNotFoundException e) {
            showToast("照片不存在");
        }
    }
 public static Intent getTakePickIntent(File f) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        return intent;
    }

三、相关权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-feature android:name="android.hardware.camera" />

四、图片的旋转角度

/**
     * 获取图片的旋转角度
     *
     * @param filepath
     * @return
     */
    public static int getExifOrientation(String filepath) {
        int degree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(filepath);
        } catch (IOException ex) {
        }
        if (exif != null) {
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
            if (orientation != -1) {
                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;
                }
            }
        }
        return degree;
    }

五、图片的基本信息

 private Map<String, String> mapDetails;

    private void showImageDetails() {
        Cursor cursor = null;
        String column = MediaStore.Images.ImageColumns.DATA;
        try {
            cursor = getContentResolver().query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
                    column + "=?", new String[]{tempImagePath}, null);

            if (cursor != null && cursor.moveToFirst()) {
                mapDetails = new LinkedHashMap<String, String>();

                mapDetails
                        .put("title",
                                cursor.getString(cursor
                                        .getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME)));

                SimpleDateFormat sdf = new SimpleDateFormat(
                        "yyyy-MM-dd HH-mm-ss"); // 实例化模板对象
                try {
                    Date times = sdf
                            .parse(cursor.getString(cursor
                                    .getColumnIndex(MediaStore.Images.Media.DATE_ADDED)));

                    mapDetails.put("times",
                            String.valueOf(times));
                } catch (ParseException e1) {
                    e1.printStackTrace();
                }

                mapDetails
                        .put("description",
                                cursor.getString(cursor
                                        .getColumnIndex(MediaStore.Images.Media.DESCRIPTION)));

                int fileSize = Integer.parseInt(cursor.getString(cursor
                        .getColumnIndex(MediaStore.Images.Media.SIZE)));
                mapDetails.put("file_size",
                        formatFileSize(fileSize));
                mapDetails
                        .put("mimetype",
                                cursor.getString(cursor
                                        .getColumnIndex(MediaStore.Images.Media.MIME_TYPE)));
                mapDetails
                        .put("height",
                                cursor.getString(cursor
                                        .getColumnIndex(MediaStore.Images.Media.HEIGHT)));
                mapDetails
                        .put("width", cursor.getString(cursor
                                .getColumnIndex(MediaStore.Images.Media.WIDTH)));

                int degree = getExifOrientation(tempImagePath);
                mapDetails.put("degree", degree + "");
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }

        text_big.setText(detailsToString());
    }

六、运行截图:



备注:遇到的问题

1、使用相机时,点击确定按钮,无反应。点击返回时,能获取到照相所得的图片 uri

有时候我们会发现用相机拍摄获取照片的时候,得到的 uri 是 null 的,这是因为android把拍摄的图片封装到bundle中传递回来,但是根据不同的机器获得相片的方式不太一样,可能有的相机能够通过inten.getData()获取到uri, 然后再根据uri获取数据的路径,在封装成bitmap,但有时候有的相机获取到的是null的,这时候我们该怎么办呢?
 其实这时候我们就应该从bundle中获取数据,通过 (Bitmap) bundle.get("data")获取到相机图片的bitmap数据。

2、下面是选择相册时,日志台中输出的错误,求解答???

0-29 17:54:48.509  30013-30013/demo.my.com.myapidemo E/ActivityThread﹕ Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver 
com.android.internal.app.ResolverActivity$1@41810fc8 that was originally registered here. Are you missing a call to unregisterReceiver()?
    android.app.IntentReceiverLeaked: Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver 
    com.android.internal.app.ResolverActivity$1@41810fc8 that was originally registered h

参考链接:http://blog.csdn.net/cherry609195946/article/details/9264409


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值