您的位置:首页 > 移动开发 > Android开发

Android 实现拍照 获取相册 图片压缩 图片旋转 图片转存

2014-07-08 14:09 423 查看
相机完整代码封装地址: http://https://github.com/zhaocheng19940105/CamaerManager
 @SuppressLint("NewApi")
public abstract class ImageSelectActivity extends BaseAudioActivity {

    private File tempFile;
    private File tempFileThumbnail;
    private static Uri fileUri;
    private Bitmap compressImage;
    private ImageSelectPopWindow menu;
    protected static final int OPEN_CAMERA_CODE = 10;// 打开相机
    protected static final int OPEN_GALLERY_CODE = 11;// 打开相册
    protected static final int CROP_PHOTO_CODE = 12;// 裁剪图片
    private int x = 0;
    private int y = 0;
    private int weight = 0;
    private int height = 0;
    private boolean isCrop = false; // 裁剪
    private static final String IMG_PREFIX_DEFAULT = "img";
    private IImageSelectedLisenterString imageSelectedLisenter;

    private void initFile() {
        if (TextUtils.isEmpty(SDCardUtil.getPath())) {
            MessageUtil.showShortToast(this, getString(R.string.no_sdcard));
            return;
        }
        String timeStamp = DateUtil.long2String(System.currentTimeMillis(),
                "yyyyMMdd_HHmmss");
        if (fileUri != null) {
            fileUri = null;
        }
        fileUri = Uri
                .fromFile(FileUtil.createFile(FileConstants
                        .getImageDirPath(this)
                        + getImagePrefix()
                        + timeStamp
                        + ".jpg"));

        SharedPreferences mPreferences = getSharedPreferences("setting", 0);
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putString(ImageSelectActivity.class.getSimpleName(),
                fileUri.getPath());
        editor.commit();
    }

    public void setCrop(int x, int y, int weight, int height) {
        this.x = x;
        this.y = y;
        this.weight = weight;
        this.height = height;
        isCrop = true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    // 截取图片
    public void cropImage(Uri uri) {
        String str = "";
        if (fileUri == null) {
            SharedPreferences mPreferences = getSharedPreferences("setting", 0);
            str = mPreferences.getString(
                    ImageSelectActivity.class.getSimpleName(), "");
        } else {
            str = fileUri.getPath();
        }
        Intent intent = new Intent(this, CropImage.class);
        intent.putExtra(CropImage.IMAGE_PATH, str);
        intent.putExtra(CropImage.SCALE, true);
        intent.putExtra(CropImage.ASPECT_X, x);
        intent.putExtra(CropImage.ASPECT_Y, y);
        intent.putExtra(CropImage.OUTPUT_X, weight);
        intent.putExtra(CropImage.OUTPUT_Y, height);
        startActivityForResult(intent, CROP_PHOTO_CODE);
    }

    /**
     * 调用相机
     */
    protected void openCamera() {
        initFile();
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 打开相机
        final Intent intent_camera = getPackageManager()
                .getLaunchIntentForPackage("com.android.camera");
        if (intent_camera != null) {
            intent.setPackage("com.android.camera");
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        startActivityForResult(intent, OPEN_CAMERA_CODE);

    }

    /**
     * 打开相册
     */
    protected void openGallery() {
        initFile();
        Intent intent = new Intent();
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        // 根据版本号不同使用不同的Action
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, OPEN_GALLERY_CODE);

    }

    /**
     * 压缩图片
     * 
     * @param path
     */
    protected void compressimg(String path) {
        if (path == null) {
            MessageUtil.showShortToast(this, getString(R.string.data_null));
            return;
        }
        tempFile = FileUtil.createFile(FileConstants.getImageDirPath(this)
                + "tmp" + System.currentTimeMillis() + ".jpg");
        tempFileThumbnail = FileUtil.createFile(tempFile.getPath().replace(
                ".jpg", "_300x300.jpg"));
        disposeImage(path);
        delOldUrl();
    }

    /**
     * 删除压缩之前的图片
     */
    public void delOldUrl() {

        if (null != tempFile) {
            if (tempFile.exists() && tempFile.length() < 1) {
                tempFile.delete();
            } else {
                if (null != imageSelectedLisenter) {
                    imageSelectedLisenter
                            .onSelected(tempFile.getAbsolutePath());
                }
            }
        }
        try {
            if (fileUri != null) {
                String fileName = fileUri.getEncodedPath();
                File file = new File(fileName);
                if (file != null && file.exists()) {
                    file.delete();
                }
                fileUri = null;
            }
            dismissMenu();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取图片文件
     * 
     * @return
     */
    protected File getImageFile() {
        if (tempFile == null) {
            return null;
        }
        if (tempFile.length() > 0) {
            return tempFile;
        }
        return null;
    }

    /**
     * 隐藏弹出菜单
     */
    private void dismissMenu() {
        if (menu != null) {
            menu.dismiss();
        }
    }

    /**
     * 弹出选择菜单
     */
    protected void showMenu() {
        if (SDCardUtil.checkSDCard()) {
            AndroidUtil.hideIME(this, true);
            menu = new ImageSelectPopWindow(this, menuClickLisenter, false,
                    null);
            // 显示窗口
            menu.showAtLocation(getRootView(), Gravity.BOTTOM
                    | Gravity.CENTER_HORIZONTAL, 0, 0); // 设置layout在PopupWindow中显示的位置
        } else {
            MessageUtil.showShortToast(this, getString(R.string.no_sdcard));
        }

    }

    protected void showMenuDel(OnClickListener clickListener) {
        AndroidUtil.hideIME(this, true);
        menu = new ImageSelectPopWindow(this, menuClickLisenter, true,
                clickListener);
        // 显示窗口
        menu.showAtLocation(getRootView(), Gravity.BOTTOM
                | Gravity.CENTER_HORIZONTAL, 0, 0); // 设置layout在PopupWindow中显示的位置
    }

    protected PopupWindow getPop() {
        return menu;
    }

    private void delUri() {
        try {
            if (fileUri != null) {
                String fileName = fileUri.getEncodedPath();
                File file = new File(fileName);
                if (file != null && file.exists()) {
                    file.delete();
                }
                fileUri = null;
            }
            dismissMenu();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /***
     * 弹出框菜单事件
     */
    private View.OnClickListener menuClickLisenter = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_take_photo:// 拍照
                openCamera();
                break;
            case R.id.btn_pick_photo:// 从相册选择
                openGallery();
                break;
            }
            dismissMenu();
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (RESULT_OK != resultCode) {
            delUri();
            return;
        }
        if (fileUri == null) {
            SharedPreferences mPreferences = getSharedPreferences("setting", 0);
            String str = mPreferences.getString(
                    ImageSelectActivity.class.getSimpleName(), "");
            fileUri = Uri.fromFile(FileUtil.createFile(str));
        }
        switch (requestCode) {
        case OPEN_CAMERA_CODE:
            cameraResult();
            break;
        case OPEN_GALLERY_CODE:
            galleryResult(data);
            break;
        case CROP_PHOTO_CODE:
            cropResult();
            break;
        default:
            break;
        }
    }

    private void cameraResult() {
        if (fileUri != null && !fileUri.getPath().equals("")) {
            if (isCrop) {
                cropPhotoForRoate(fileUri.getPath());
                cropImage(fileUri);
            } else {
                compressimg(fileUri.getPath());
            }
        } else {
            MessageUtil.showShortToast(this, getString(R.string.path_error));
        }
    }

    private void galleryResult(Intent data) {
        if (data == null) {
            MessageUtil.showShortToast(ImageSelectActivity.this,
                    getString(R.string.data_null));
            return;
        }
        if (fileUri != null) {
            InputStream inputStream;
            try {
                inputStream = getContentResolver().openInputStream(
                        data.getData());
                if (inputStream == null) {
                    MessageUtil.showShortToast(getApplicationContext(),
                            getString(R.string.data_null));
                    return;
                }

                FileOutputStream fileOutputStream = new FileOutputStream(
                        fileUri.getPath());
                copyStream(inputStream, fileOutputStream);
                fileOutputStream.close();
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (isCrop) {
                cropPhotoForRoate(fileUri.getPath());
                cropImage(fileUri);
            } else {
                compressimg(fileUri.getPath());
            }
        }
    }

    private void cropResult() {
        if (fileUri != null) {
            compressimg(fileUri.getPath());
        } else {
            MessageUtil.showShortToast(getApplicationContext(),
                    getString(R.string.data_null));
        }
    }

    public static void copyStream(InputStream input, OutputStream output)
            throws IOException {

        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }

    protected void setImageSelectedLisenterString(
            IImageSelectedLisenterString imageSelectedLisenter) {
        this.imageSelectedLisenter = imageSelectedLisenter;
    }

    /**
     * 选择处理后的图片文件名称前缀
     * 
     * @return
     */
    protected String getImagePrefix() {
        return IMG_PREFIX_DEFAULT;
    }

    /***
     * 
     * @return
     */
    protected abstract View getRootView();

    /***
     * 弹出菜单
     */
    private class ImageSelectPopWindow extends PopupWindow {
        private LinearLayout ll_show_del;
        private TextView btn_take_photo, btn_pick_photo, btn_cancel;
        private View mMenuView;

        public ImageSelectPopWindow(Activity context,
                View.OnClickListener itemsOnClick, boolean isdel,
                OnClickListener listener) {
            super(context);
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            mMenuView = inflater.inflate(R.layout.alert_dialog, null);
            ll_show_del = (LinearLayout) mMenuView
                    .findViewById(R.id.ll_show_del);
            if (isdel && listener != null) {
                ll_show_del.setVisibility(View.VISIBLE);
                ll_show_del.setOnClickListener(listener);
            } else {
                ll_show_del.setVisibility(View.GONE);
            }
            btn_take_photo = (TextView) mMenuView
                    .findViewById(R.id.btn_take_photo);
            btn_pick_photo = (TextView) mMenuView
                    .findViewById(R.id.btn_pick_photo);
            btn_cancel = (TextView) mMenuView.findViewById(R.id.btn_cancel);
            // 取消按钮
            btn_cancel.setOnClickListener(new View.OnClickListener() {

                public void onClick(View v) {
                    // 销毁弹出框
                    dismiss();
                }
            });
            // 设置按钮监听
            btn_pick_photo.setOnClickListener(itemsOnClick);
            btn_take_photo.setOnClickListener(itemsOnClick);
            // 设置SelectPicPopupWindow的View
            this.setContentView(mMenuView);
            // 设置SelectPicPopupWindow弹出窗体的宽
            this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            // 设置SelectPicPopupWindow弹出窗体的高
            this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            // 设置SelectPicPopupWindow弹出窗体可点击
            this.setFocusable(true);
            // 设置SelectPicPopupWindow弹出窗体动画效果
            this.setAnimationStyle(R.style.PopupAnimation);
            // 实例化一个ColorDrawable颜色为半透明
            ColorDrawable dw = new ColorDrawable(R.color.transparent_50);
            // 设置SelectPicPopupWindow弹出窗体的背景
            this.setBackgroundDrawable(dw);
            // mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框
            mMenuView.setOnTouchListener(new View.OnTouchListener() {

                public boolean onTouch(View v, MotionEvent event) {

                    int height = mMenuView.findViewById(R.id.pop_layout)
                            .getTop();
                    int y = (int) event.getY();
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        if (y < height) {
                            dismiss();
                        }
                    }
                    return true;
                }
            });
        }
    }

    /**
     * 获取图片的旋转角度
     * 
     * @Title: readPictureDegree
     * @param path
     * @return int
     * @date 2013-11-27 上午9:22:33
     */
    private static int readPictureDegree(String path) {
        int degree = 0;
        try {

            ExifInterface exifInterface = new ExifInterface(path);
            // 得到照片的信息,ExifInterface.TAG_MAKE拍照设备型号,ExifInterface.TAG_MODEL拍照设备品牌,ExifInterface.TAG_ORIENTATION照片旋转角度
            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:
                degree = 0;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    // /**
    // * 裁剪前判断图片旋转图
    // */
    private void cropPhotoForRoate(String path) {

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        // Calculate inSampleSize
        final float s = options.outWidth / (float) options.outHeight;

        options.inPreferredConfig = Config.ARGB_8888;
        options.inPurgeable = true;
        options.inInputShareable = true;
        if (s >= ImImageViewUtil.WIDESMALLSCALE) {
            // 宽矮图片
            options.inSampleSize = calculateInSampleSize(options, 1600, 800);
        } else if (s <= ImImageViewUtil.GROWSMALLSCALE) {
            // 细长图片 避免失真
            options.inSampleSize = calculateInSampleSize(options, 480, 1600);
        } else {
            // 普通图片
            options.inSampleSize = calculateInSampleSize(options, 480, 800);
        }
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bm = BitmapFactory.decodeFile(path, options);
        if (bm == null) {
            MessageUtil.showShortToast(this, getString(R.string.image_error));
            return;
        }
        Bitmap rotateBitmap = rotateBitmap(bm, readPictureDegree(path));

        // 同步返回
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        rotateBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        try {
            FileOutputStream outputStream = new FileOutputStream(
                    fileUri.getPath());
            baos.writeTo(outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static Bitmap rotateBitmap(Bitmap bitmap, int rotate) {
        if (bitmap == null)
            return null;

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        // Setting post rotate to 90
        Matrix mtx = new Matrix();
        mtx.postRotate(rotate);
        Bitmap createBitmap = null;
        try {
            createBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
        } catch (OutOfMemoryError error) {

        }
        if (createBitmap != bitmap) {
            bitmap.recycle();
        }
        return createBitmap;
    }

    protected void getImagePath(String str) {
        if (compressImage!=null && !compressImage.isRecycled()) {
            compressImage.recycle();
            compressImage=null;
        }
    }

    private void getIntalnalImagePath(final String str) {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                getImagePath(str);

            }
        });
    }

    public void disposeImage(final String path) {

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        // Calculate inSampleSize
        final float s = options.outWidth / (float) options.outHeight;

        options.inPreferredConfig = Config.RGB_565;
        options.inPurgeable = true;
        options.inInputShareable = true;
        if (s >= ImImageViewUtil.WIDESMALLSCALE) {
            // 宽矮图片
            options.inSampleSize = calculateInSampleSize(options, 1600, 800);
        } else if (s <= ImImageViewUtil.GROWSMALLSCALE) {
            // 细长图片 避免失真
            options.inSampleSize = calculateInSampleSize(options, 480, 1600);
        } else {
            // 普通图片
            options.inSampleSize = calculateInSampleSize(options, 400, 800);
        }
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;

        Bitmap bm = null;
        try {
            bm = BitmapFactory.decodeFile(path, options);
        } catch (OutOfMemoryError e) {
            bm = BitmapFactory.decodeResource(getResources(),
                    ImImageViewUtil.getImageErrorBG());
        }
        bm = compressImage(bm);
        if (bm == null) {
            MessageUtil.showShortToast(this, getString(R.string.image_error));
            return;
        }
        compressImage = rotateBitmap(bm, readPictureDegree(path));
        // 写入原图
        if (imageSelectedLisenter == null) {
            new Thread() {
                // 异步返回
                public void run() {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    compressImage.compress(Bitmap.CompressFormat.JPEG, 100,
                            baos);
                    FileOutputStream outputStream = null;
                    try {
                        outputStream = new FileOutputStream(tempFile);
                        baos.writeTo(outputStream);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                            if (baos != null) {
                                baos.close();
                            }
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    Bitmap cutBitmapWidth = null;
                    if (s >= ImImageViewUtil.WIDESMALLSCALE) {
                        // 宽矮图片
                        cutBitmapWidth = cutBitmapWidth(compressImage);
                    } else if (s <= ImImageViewUtil.GROWSMALLSCALE) {
                        // 细长图片 避免失真
                        cutBitmapWidth = cutBitmapHight(compressImage);
                    } else {
                        cutBitmapWidth = ImImageViewUtil.zoomImg(compressImage,
                                ImImageViewUtil.MAXWIDTH,
                                ImImageViewUtil.MAXHEIGHT, true);
                        // 普通图片
                    }
                    compressImage = cutBitmapWidth;
                    ByteArrayOutputStream baosThum = new ByteArrayOutputStream();
                    compressImage.compress(Bitmap.CompressFormat.JPEG, 100,
                            baosThum);
                    try {
                        outputStream = new FileOutputStream(tempFileThumbnail);
                        baosThum.writeTo(outputStream);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if (outputStream != null) {
                        try {
                            outputStream.close();
                            if (baosThum != null) {
                                baosThum.close();
                            }
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                    }
                    getIntalnalImagePath(tempFile.getPath());
                };

            }.start();
        } else {
            // 同步返回
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            compressImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            try {
                FileOutputStream outputStream = new FileOutputStream(tempFile);
                baos.writeTo(outputStream);
            } catch (Exception e) {
                e.printStackTrace();
            }
            getIntalnalImagePath(tempFile.getPath());

        }

    }

    public Bitmap cutBitmapWidth(Bitmap bm) {
        int width = bm.getWidth() / 2;
        Bitmap createBitmap = null;
        if (width - ImImageViewUtil.MAXWIDTH / 2 > 0) {
            createBitmap = Bitmap.createBitmap(bm, bm.getWidth() / 2
                    - ImImageViewUtil.MAXWIDTH / 2, 0,
                    ImImageViewUtil.MAXWIDTH, bm.getHeight());
        } else {
            createBitmap = Bitmap.createBitmap(bm, bm.getWidth() / 2, 0,
                    ImImageViewUtil.MAXWIDTH, bm.getHeight());
        }
        if (bm != createBitmap) {
            bm.recycle();
            bm = null;
        }
        return createBitmap;
    }

    public Bitmap cutBitmapHight(Bitmap bm) {
        int height = bm.getHeight() / 2;
        Bitmap createBitmap = null;

        if (height - ImImageViewUtil.MAXHEIGHT / 2 > 0) {
            createBitmap = Bitmap.createBitmap(bm, 0, bm.getHeight() / 2
                    - ImImageViewUtil.MAXHEIGHT / 2, bm.getWidth(),
                    ImImageViewUtil.MAXHEIGHT);
        } else {
            createBitmap = Bitmap.createBitmap(bm, 0, bm.getHeight() / 2,
                    bm.getWidth(), ImImageViewUtil.MAXHEIGHT);
        }
        if (bm != createBitmap) {
            bm.recycle();
            bm = null;
        }
        return createBitmap;
    }

    private Bitmap compressImage(Bitmap image) {
        if (image != null) {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
            int options = 100;
            while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();// 重置baos即清空baos
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
                options -= 10;// 每次都减少10

            }
            image.recycle();
            ByteArrayInputStream isBm = new ByteArrayInputStream(
                    baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
            Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
            try {
                baos.close();
                isBm.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return bitmap;
        } else {
            return null;
        }
    }

    private static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will
            // guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
        }

        return inSampleSize;
    }

    /**
     * 图片选择回调接口
     */
    public interface IImageSelectedLisenterString {
        /**
         * 选中图片后的处理
         * 
         * @param imgPath
         */
        public void onSelected(String imgPath);

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: