博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
拍照、本地图片工具类(兼容至Android7.0)
阅读量:5063 次
发布时间:2019-06-12

本文共 27863 字,大约阅读时间需要 92 分钟。

 拍照、本地图片工具类:解决了4.4以上剪裁会提示“找不到文件”和6.0动态授予权限,及7.0报FileUriExposedException异常问题。

package com.hb.weex.util;import android.Manifest;import android.app.Activity;import android.app.Dialog;import android.content.ClipData;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.provider.MediaStore;import android.support.v4.app.FragmentActivity;import android.support.v4.content.FileProvider;import android.view.View;import android.widget.Button;import com.hb.common.android.util.Log;import com.hb.weex.R;import com.hb.weex.util.ToastUtil;import com.hb.weex.util.UploadAvatarUtil;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Iterator;import java.util.List;import kr.co.namee.permissiongen.GrantPermissionActivity;import kr.co.namee.permissiongen.PermissionGen;import kr.co.namee.permissiongen.internal.Utils;/** * 拍照管理的类 * Created by cjy on 2017/4/03. */public class TakePhotoManager implements View.OnClickListener,GrantPermissionActivity.OnGrantedListener {    /**     * 权限列表:写权限 读权限 调用摄像头权限     */    private static final String[] PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,            Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA};    /* 上下文 */    private Activity context;    /* 对话框 */    private Dialog mSelectPhotoDialog;    /* 图片的存储地址-父路径 */    private String mHeadImageFileParentPath = "";    /* 照相机拍照后的照片 */    private String mCameraImageFileName = "";    /* 头像名称 */    private String mHeadImageFileName = "";    private Button mBtnTakePhoto;//拍照    private Button mBtnPickPhoto;//选择本地图片    private Button mBtnCancel;//取消    private Uri imageUri;//原图保存地址    public TakePhotoManager(Activity context) {        this.context = context;        mHeadImageFileParentPath = Environment.getExternalStorageDirectory() + File.separator+ context.getPackageName()+File.separator;        mCameraImageFileName = "temp_camera_image.jpg";        mHeadImageFileName = "tmp_head_image.jpg";    }    public void setmHeadImageFileParentPath(String mHeadImageFileParentPath) {        this.mHeadImageFileParentPath = mHeadImageFileParentPath;    }    public void setmCameraImageFileName(String mCameraImageFileName) {        this.mCameraImageFileName = mCameraImageFileName;    }    public void setmHeadImageFileName(String mHeadImageFileName) {        this.mHeadImageFileName = mHeadImageFileName;    }    /**     * 显示头像弹出窗     */    public void showSelectPhotoDialog() {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//23            //Android6.0及以上,需要动态授予权限            // 验证所有权限是否都已经授权了            List
deniedPermissions = Utils.findDeniedPermissions(this.context, PERMISSIONS); if (deniedPermissions.size() == 0) { showDialog(); } else { Intent intent = new Intent(this.context, GrantPermissionActivity.class); intent.putExtra(GrantPermissionActivity.PARAM_PERMISSION_NAME_LIST, PERMISSIONS); GrantPermissionActivity.mGrantedListener = this; this.context.startActivity(intent); } }else{ showDialog(); } } private void showDialog(){ View view = context.getLayoutInflater().inflate(R.layout.dlg_select_photo, null); mBtnTakePhoto = (Button) view.findViewById(R.id.btn_take_photo); mBtnPickPhoto = (Button) view.findViewById(R.id.btn_pick_photo); mBtnCancel = (Button) view.findViewById(R.id.btn_cancel); mBtnTakePhoto.setOnClickListener(this); mBtnPickPhoto.setOnClickListener(this); mBtnCancel.setOnClickListener(this); mSelectPhotoDialog = UploadAvatarUtil.createDialog(context, view, R.style.transparentFrameWindowStyle, R.style.select_photo_dialog_animstyle); } /** * 关闭头像弹出窗 */ public void hideSelectPhotoDialog() { if (mSelectPhotoDialog != null && mSelectPhotoDialog.isShowing()) { mSelectPhotoDialog.dismiss(); } } /** * 拍照 */ public void takePhoto(Activity context, String imgUrl, String imageFileNameTemp) { File file = UploadAvatarUtil.getFile(imgUrl, imageFileNameTemp); // 打开相机 Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //FileUriExposedException这个异常只会在Android 7.0 + 出现,当app使用file:// url 共享给其他app时, 会抛出这个异常。 //因为在android 6.0 + 权限需要 在运行时候检查, 其他app 可能没有读写文件的权限, 所以google在7.0的时候加上了这个限制。官方推荐使用 FileProvider 解决这个问题。 intentFromCapture.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION ); //添加这一句表示对目标应用临时授权该Uri所代表的文件 imageUri = FileProvider.getUriForFile(context, "com.hb.weex.accountant.fileprovider", file);//通过FileProvider创建一个content类型的Uri } else { imageUri = Uri.fromFile(file); } intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI context.startActivityForResult(intentFromCapture, UploadAvatarUtil.CAMERA_REQUEST_CODE); } /** * 选择本地图片 */ public void pickPhoto(Activity context) { Intent intent = new Intent(Intent.ACTION_PICK); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); context.startActivityForResult(intent, UploadAvatarUtil.IMAGE_REQUEST_CODE); } public Object onActivityResult(Context context,int requestCode, int resultCode, Intent data) { //关闭头像弹出窗 hideSelectPhotoDialog(); if (resultCode != Activity.RESULT_CANCELED) { switch (requestCode) { case UploadAvatarUtil.IMAGE_REQUEST_CODE:// 选择本地图片返回 if (null != data) {//为了取消选取不报空指针用的 imageUri = data.getData(); startPhotoZoom(context, imageUri , 1); } break; case UploadAvatarUtil.CAMERA_REQUEST_CODE:// 拍照返回 if (UploadAvatarUtil.hasSdcard()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//24 startPhotoZoom(context, imageUri, 0); }else{ File tempFile = getFileTmp(); startPhotoZoom(context, Uri.fromFile(tempFile), 0); } } else { ToastUtil.showToast(context, context.getResources().getString(R.string.find_sdcard_none)); } break; case UploadAvatarUtil.CLIP_REQUEST_CODE:// 裁剪完成,删除照相机缓存的图片 Bitmap imageBitmap = null; //获取头像文件 File file = getTmpHeadImage(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){//24 try { imageBitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(imageUri)); } catch (FileNotFoundException e) { e.printStackTrace(); } }else { if (!file.exists()) { return null; } imageBitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); } if (imageBitmap == null) { return null; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); byte[] userImageData = baos.toByteArray(); //修改个人头像 HashMap
result = new HashMap
(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { result.put("path", file.getAbsolutePath()); } result.put("data",userImageData); return result; } } return null; } /** * 裁剪图片 * * @param uri from 1代表本地照片的裁剪,0代表拍照后的裁剪 */ public void startPhotoZoom(Context context, Uri uri, int from) { Intent intent = new Intent("com.android.camera.action.CROP"); String url = convertPath(context, uri); /** * 当满足:SDK>4.0、选择本地照片操作、裁剪框为圆形(或者说路径与之前版本有异)三个条件时 * 进行转换操作 */ if (Build.VERSION.SDK_INT >= 19 && from == 1 && url != null) { intent.setDataAndType(Uri.fromFile(new File(url)), "image/*"); } else { intent.setDataAndType(uri, "image/*"); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION ); } // 设置裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 100); intent.putExtra("outputY", 100); Uri uriPath; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {//小于24 uriPath = Uri.fromFile(UploadAvatarUtil.getFile(mHeadImageFileParentPath, mHeadImageFileName)); }else{ uriPath = imageUri; } intent.putExtra(MediaStore.EXTRA_OUTPUT, uriPath); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("return-data", false); //intent.putExtra("return-data", true); //return-data为true时,会直接返回bitmap数据,但是大图裁剪时会出现问题。 //设置为false比较好,但是,需要指定MediaStore.EXTRA_OUTPUT,来保存裁剪之后的图片 ((Activity)context).startActivityForResult(intent, UploadAvatarUtil.CLIP_REQUEST_CODE); } /** * 删除缓存的头像 */ public void deleteHeadCache() { UploadAvatarUtil.deleteLocalImage(mHeadImageFileParentPath, mHeadImageFileName); } /** * 获取文件对象---照相机拍照的 * * @return */ public File getFileTmp() { return UploadAvatarUtil.getFile(mHeadImageFileParentPath, mCameraImageFileName); } /** * 获取裁剪之后的图片文件 */ public File getTmpHeadImage(){ return UploadAvatarUtil.getFile(mHeadImageFileParentPath,mHeadImageFileName); } /** * 删除照相机拍照的图片 */ public void deleteCameraImage() { UploadAvatarUtil.deleteLocalImage(mHeadImageFileParentPath, mCameraImageFileName); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_take_photo: takePhoto(context, mHeadImageFileParentPath, mCameraImageFileName); break; case R.id.btn_pick_photo: pickPhoto(context); break; case R.id.btn_cancel: hideSelectPhotoDialog(); break; } } /** * 将uri转换成字符串 * 解决4.4版本以上获取到的uri是图片名称而非图片路径,导致剪裁图片时提示无法加载图片的问题 * 详细的解决方案,请参考这篇文章 * 当安卓的版本比较高时(如4.4),选择本地相册可能会返回“无法加载此图片” * 原因:正常uri是file://...而高版本是content://... * 所以需要一个转换操作 * * @param context * @param uri * @return */ public String convertPath(final Context context, final Uri uri) { //代表SDK4.4需要反射的类 Class getClass = null; //代表两个SDK4.4里面反射的方法 Method isMethod; Method getMethod; String stringMethod = ""; //判断当前版本是否大于4.0 final boolean isKitKat = Build.VERSION.SDK_INT >= 19; try { /** * 获取类和方法 * 方法传参方式 * 获取返回值 */ getClass = Class.forName("android.provider.DocumentsContract"); getMethod = getClass.getMethod("getDocumentId", new Class[]{Uri.class}); isMethod = getClass.getMethod("isDocumentUri", new Class[]{Context.class, Uri.class}); Object isResult = isMethod.invoke(getClass, new Object[]{context, uri}); Object getResult = getMethod.invoke(getClass, new Object[]{uri}); stringMethod = (String) getResult; if (!(Boolean) isResult) return null; //当手机SDK大于4.4且路径类型与以往不同时(isShot为True时往往裁剪框是圆形,即是新类型的路径) if (isKitKat) { if (isExternalStorageDocument(uri)) { final String docId = stringMethod; final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } else if (isDownloadsDocument(uri)) { final String id = stringMethod; final Uri contentUri = ContentUris.withAppendedId( //高版本的路径不同于低版本,需要转换 Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } else if (isMediaDocument(uri)) { final String docId = stringMethod; final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{ split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } else if ("content".equalsIgnoreCase(uri.getScheme())) { if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } catch (Exception e) { Log.e("error", e.toString()); } return null; } //获取String类型的路径 public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } @Override public void onGrantSuccess() { showDialog(); }}

在7.0 上使用FileProvider来获取图片的路径,需要以下几步设置:

(1)在Androidmainfest的Application根标签中设置provider,相机,读写文件权限

(2)在res/xml目录中创建文件file_paths.xml:

注:文件中涉及的其他文件如下:

  (1)动态权限授权使用第三方

(2)UploadAvatarUtil.java

package com.hb.weex.util;import android.app.Activity;import android.app.Dialog;import android.content.Context;import android.content.Intent;import android.graphics.*;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.graphics.drawable.LayerDrawable;import android.net.Uri;import android.os.Environment;import android.provider.MediaStore;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.view.WindowManager;import com.hb.common.android.util.Log;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;/** * 上传用户头像 * 功能如下: * 1、保存图片到本地、删除本地图片 * 2、拍照、从图库中选择照片、剪裁 * 3、创建文件目录、获取文件对象 * 4、检查Sdcard是否存在 * 5、创建圆角矩形图片 * 6、创建圆角图片 * 7、自定义从下往上显示的Dialog(模仿QQ退出效果) * 8、图片上绘制文字 * Created by cjy on 2015/4/9. */public class UploadAvatarUtil {    public static final int IMAGE_REQUEST_CODE = 0;  //选择本地图片    public static final int CAMERA_REQUEST_CODE = 1; //拍照    public static final int CLIP_REQUEST_CODE = 2;   //裁剪    private static final int DEFAULT_TEXT_SIZE = 32;//默认的字体大小    /**     * 检查是否存在sdcard     *     * @return     */    public static boolean hasSdcard() {        String state = Environment.getExternalStorageState();        if (state.equals(Environment.MEDIA_MOUNTED)) {            return true;        } else {            return false;        }    }    /**     * 创建文件目录     *     * @param filePath 文件路径     */    public static File makeFileDir(String filePath) {        File file = null;        try {            file = new File(filePath);            if (!file.exists()) {                file.mkdirs();            }        } catch (Exception e) {            e.printStackTrace();        }        return file;    }    /**     * 获取文件对象     *     * @param filePath 文件路径     * @param fileName 文件名称     * @return     */    public static File getFile(String filePath, String fileName) {        File file = null;        //创建文件目录        makeFileDir(filePath);        try {            file = new File(filePath + fileName);        } catch (Exception e) {            e.printStackTrace();        }        return file;    }    /**     * 保存图片到本地     *     * @param imgUrl        图片路径     * @param imageFileName 图片名称     * @param bitmap     */    public static void saveLocalImage(String imgUrl, String imageFileName, Bitmap bitmap) {        try {            File f = getFile(imgUrl, imageFileName);            FileOutputStream fOut = new FileOutputStream(f);            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);            fOut.flush();            fOut.close();        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 删除本地图片     *     * @param imgUrl        图片路径     * @param imageFileName 图片名称     */    public static void deleteLocalImage(String imgUrl, String imageFileName) {        File f = getFile(imgUrl, imageFileName);        if (f.isFile() && f.exists()) {            f.delete();        }    }    /**     * 绘制圆角矩形图片     * 圆形 x=120,y=120,outerRadiusRat=60     *     * @param x     * @param y     * @param image     * @param outerRadiusRat     * @return     */    public static Bitmap createFramedPhoto(int x, int y, Bitmap image,                                           float outerRadiusRat) {        // 根据源文件新建一个darwable对象        Drawable imageDrawable = new BitmapDrawable(image);        // 新建一个新的输出图片        Bitmap output = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(output);        // 新建一个矩形        RectF outerRect = new RectF(0, 0, x, y);        // 产生一个白色的圆角矩形        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);        paint.setColor(Color.RED);        canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);        // 将源图片绘制到这个圆角矩形上        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        imageDrawable.setBounds(0, 0, x, y);        canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);        imageDrawable.draw(canvas);        canvas.restore();        return output;    }    /**     * 选择本地图片     */    public static void pickPhoto(Context context) {        Intent intentFromGallery = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        intentFromGallery.setType("image/*"); // 设置文件类型        intentFromGallery.setAction(Intent.ACTION_GET_CONTENT);        ((Activity) context).startActivityForResult(intentFromGallery, IMAGE_REQUEST_CODE);    }    /**     * 拍照     */    public static void takePhoto(Context context, String imgUrl, String imageFileNameTemp) {        // 打开相机        Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        // 判断存储卡是否可以用,存储缓存图片        if (hasSdcard()) {            intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,                    Uri.fromFile(getFile(imgUrl, imageFileNameTemp)));        }        ((Activity) context).startActivityForResult(intentFromCapture, CAMERA_REQUEST_CODE);    }    /**     * 裁剪图片     *     * @param uri     */    public static void startPhotoZoom(Context context, Uri uri) {        Intent intent = new Intent("com.android.camera.action.CROP");        intent.setDataAndType(uri, "image/*");        // 设置裁剪        intent.putExtra("crop", "true");        // aspectX aspectY 是宽高的比例        intent.putExtra("aspectX", 1);        intent.putExtra("aspectY", 1);        // outputX outputY 是裁剪图片宽高        intent.putExtra("outputX", 200);        intent.putExtra("outputY", 200);        intent.putExtra("return-data", true);//        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);//        intent.putExtra("return-data", false);//设置为不返回数据        ((Activity) context).startActivityForResult(intent, CLIP_REQUEST_CODE);    }    /**     * 创建指定样式、指定动画的Dialog     *     * @param context     * @param view        Dialog的布局     * @param styleId     Dialog的样式     * @param animStyleId Dialog的动画样式     * @return     */    public static Dialog createDialog(Context context, View view, int styleId, int animStyleId) {        Dialog mSelectPhotoDialog = new Dialog(context, styleId);        mSelectPhotoDialog.setContentView(view);        Window window = mSelectPhotoDialog.getWindow();        // 设置显示动画        window.setWindowAnimations(animStyleId);        WindowManager.LayoutParams wl = window.getAttributes();        wl.x = 0;        wl.y = ((Activity) context).getWindowManager().getDefaultDisplay().getHeight();        // 以下这两句是为了保证按钮可以水平满屏        wl.width = ViewGroup.LayoutParams.MATCH_PARENT;        wl.height = ViewGroup.LayoutParams.WRAP_CONTENT;        // 设置显示位置        mSelectPhotoDialog.onWindowAttributesChanged(wl);        // 设置点击外围解散        mSelectPhotoDialog.setCanceledOnTouchOutside(true);        mSelectPhotoDialog.show();        return mSelectPhotoDialog;    }    /**     * 第1种方法:图片上绘制文字     *     * @param context     * @param drawableId     * @param text     * @param color     * @return     */    public static Bitmap drawTextAtBitmap(Context context, int drawableId, String text, int color, float density) {        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableId);        int[] size = getBitmapSize(context, drawableId);//        Log.e("density", density + "");        int x = size[0];        int y = size[1];//        int x = (int) (size[0] * density);//        int y = (int) (size[1] * density);//        Log.e("x", x + "");//        Log.e("y", y + "");//        bitmap = getScaleBitmap(context,bitmap);        // 创建一个和原图同样大小的位图        Bitmap newbit = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(newbit);        Paint paint = new Paint();        // 贴图 在原始位置0,0插入原图        canvas.drawBitmap(bitmap, 0, 0, paint);        paint.setColor(color);        int textSize = DEFAULT_TEXT_SIZE;        if (density >= 3) {            textSize *= (density + 1);        } else if (density >= 2) {            textSize *= (density + 0.1);        }        paint.setTextSize(textSize);        paint.setTextAlign(Paint.Align.CENTER);        // 在原图指定位置写上字//        canvas.drawText(text, x / 2 - 10 * density, y / 2, paint);        canvas.drawText(text, x / 2, y / 2 + 20 * (density-1) + 2, paint);        canvas.save(Canvas.ALL_SAVE_FLAG);        // 存储        canvas.restore();        return newbit;    }    /**     * 图片叠加     *     * @param bitmap1     * @param bitmap2     * @return     */    public static Bitmap layerBitmap(Bitmap bitmap1, Bitmap bitmap2) {        // copy 防止出现Immutable bitmap passed to Canvas constructor错误        bitmap1 = bitmap1.copy(Bitmap.Config.ARGB_8888, true);        Bitmap newBitmap = null;        newBitmap = Bitmap.createBitmap(bitmap1);        Canvas canvas = new Canvas(newBitmap);        Paint paint = new Paint();        int w = bitmap1.getWidth();        int h = bitmap1.getHeight();        int w_2 = bitmap2.getWidth();        int h_2 = bitmap2.getHeight();        paint.setColor(Color.GRAY);        paint.setAlpha(125);        canvas.drawRect(0, 0, bitmap1.getWidth(), bitmap1.getHeight(), paint);        paint = new Paint();        canvas.drawBitmap(bitmap2, Math.abs(w - w_2) / 2,                Math.abs(h - h_2) / 2, paint);        canvas.save(Canvas.ALL_SAVE_FLAG);        // 存储新合成的图片        canvas.restore();        return newBitmap;    }    /**     * 图片叠加     *     * @param bitmap1     * @param bitmap2     * @return     */    public static LayerDrawable layerDrawable(Bitmap bitmap1, Bitmap bitmap2) {        Drawable[] array = new Drawable[2];        array[0] = new BitmapDrawable(bitmap1);        array[1] = new BitmapDrawable(bitmap2);        LayerDrawable la = new LayerDrawable(array);        // 其中第一个参数为层的索引号,后面的四个参数分别为left、top、right和bottom        la.setLayerInset(0, 0, 0, 0, 0);        la.setLayerInset(1, 10, 10, 10, 10);        return la;    }    /**     * 获取Bitmap的宽高     *     * @param context     * @param drawableId 图片id     * @return     */    private static int[] getBitmapSize(Context context, int drawableId) {        int[] size = new int[2];        BitmapFactory.Options opts = new BitmapFactory.Options();        opts.inJustDecodeBounds = true;        BitmapFactory.decodeResource(context.getResources(), drawableId, opts);        int width = opts.outWidth;        int height = opts.outHeight;        size[0] = width;        size[1] = height;        return size;    }    /**     * 等比例缩放     *     * @param context     * @param bitmap     * @return     */    public static Bitmap getScaleBitmap(Context context, Bitmap bitmap) {        int[] screen = ScreenPixelsUtil.getScreenPixels(context);        Matrix matrix = new Matrix();        int width = bitmap.getWidth();        int height = bitmap.getHeight();        Log.e("Width", width + "");        Log.e("Height", height + "");        //屏幕宽度/图片宽度        float w = screen[0] / width;        float h = screen[1] / height;        matrix.postScale(w, h);// 获取缩放比例        // 根据缩放比例获取新的位图        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);        return newbmp;    }}

(3)资源文件:

 dlg_select_photo.xml

styles.xml

drawable

//photo_dialog_in_anim.xml
//photo_dialog_out_anim.xml

  

  

  

  

转载于:https://www.cnblogs.com/hacjy/p/6723611.html

你可能感兴趣的文章
python成长之路【第二篇】:列表和元组
查看>>
R-CNN论文详解(转载)
查看>>
关于矩阵的特征向量和特征值的含义
查看>>
MTK Android 标准编译命令
查看>>
Autofac 组件、服务、自动装配
查看>>
有一种力量叫坚持
查看>>
vs2010+qt4.8.6
查看>>
FZU 2057 家谱(dfs)
查看>>
[转]C#如何在ListView失去焦点的情况下仍然保持Item高亮
查看>>
MATLAB的crack安装小曲
查看>>
JavaScript方法splice()和slice()
查看>>
Windows_Linux系统环境中搭建私有云直播流媒体服务
查看>>
曾有一个人,爱我如生命(3)
查看>>
[转载]oracle删除数据后的恢复
查看>>
iOS 关于UITabVIew刷新的几种方法(针对初学者)
查看>>
B广搜深搜
查看>>
nyoj-----127星际之门(一)
查看>>
iOS中从相机中选取多张照片
查看>>
ghj1222的代码规范
查看>>
Http code 解析
查看>>