Android调用摄像机,保存图片,添加水印,适配5.0以上版本

公司最近在做一款办公用app,需要用到拍照功能,并添加水印,国际萌新惯例先问下度娘,看了好些资料,埋了一些坑,零零散散总算整理出来了一套方案,具体引用了哪些兄台的也忘记了,总之先贡献出来,希望能帮助到可以用到的兄弟,废话不多说了,上代码先。

众所周知的清单文件权限申请走一波

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--相机所需权限-->
<uses-permission android:name="android.permission.CAMERA"/>
5.0以后,Android的权限申请有了新的变动,不仅要在清单文件里注册,还要进行动态的权限申请,准备了一个公共的权限动态申请的Activity,把平时能用到的权限直接一步到位全部申请了先。

public class CheckPermissionsActivity extends BaseActivity
        implements
        ActivityCompat.OnRequestPermissionsResultCallback {
    /**
     * 需要进行检测的权限数组
     */
    protected String[] needPermissions = {
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.READ_PHONE_STATE
    };

    private static final int PERMISSON_REQUESTCODE = 0;

    /**
     * 判断是否需要检测,防止不停的弹框
     */
    private boolean isNeedCheck = true;

    @Override
    protected void onResume() {
        super.onResume();
        if (isNeedCheck) {
            checkPermissions(needPermissions);
        }
    }

    /**
     * @param
     * @since 2.5.0
     */
    private void checkPermissions(String... permissions) {
        List<String> needRequestPermissonList = findDeniedPermissions(permissions);
        if (null != needRequestPermissonList
                && needRequestPermissonList.size() > 0) {
            ActivityCompat.requestPermissions(this,
                    needRequestPermissonList.toArray(
                            new String[needRequestPermissonList.size()]),
                    PERMISSON_REQUESTCODE);
        }
    }

    /**
     * 获取权限集中需要申请权限的列表
     *
     * @param permissions
     * @return
     * @since 2.5.0
     */
    private List<String> findDeniedPermissions(String[] permissions) {
        List<String> needRequestPermissonList = new ArrayList<String>();
        for (String perm : permissions) {
            if (ContextCompat.checkSelfPermission(this,
                    perm) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.shouldShowRequestPermissionRationale(
                    this, perm)) {
                needRequestPermissonList.add(perm);
            }
        }
        return needRequestPermissonList;
    }

    /**
     * 检测是否说有的权限都已经授权
     *
     * @param grantResults
     * @return
     * @since 2.5.0
     */
    private boolean verifyPermissions(int[] grantResults) {
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] paramArrayOfInt) {
        if (requestCode == PERMISSON_REQUESTCODE) {
            if (!verifyPermissions(paramArrayOfInt)) {
                showMissingPermissionDialog();
                isNeedCheck = false;
            }
        }
    }

    /**
     * 显示提示信息
     *
     * @since 2.5.0
     */
    private void showMissingPermissionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.notifyTitle);
        builder.setMessage(R.string.notifyMsg);

        // 拒绝, 退出应用
        builder.setNegativeButton(R.string.cancel,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                });

        builder.setPositiveButton(R.string.setting,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startAppSettings();
                    }
                });

        builder.setCancelable(false);

        builder.show();
    }

    /**
     * 启动应用的设置
     *
     * @since 2.5.0
     */
    private void startAppSettings() {
        Intent intent = new Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            this.finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}

第一步,xml布局走先

懒人,直接粘贴项目代码,类似“

@dimen/margen_10
”边距的话,自己设置就行了

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/margen_10"
    android:background="@color/white"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/margen_20"
        android:layout_marginTop="@dimen/margen_10"
        android:text="*门头照"/>

    <ImageView
        android:id="@+id/take_photos_1"
        android:layout_width="@dimen/photo_w"
        android:layout_height="@dimen/photo_h"
        android:layout_marginBottom="@dimen/margen_20"
        android:layout_marginTop="@dimen/margen_10"
        android:src="@drawable/selector_camera_press"/>
</LinearLayout>

第二步 Activity关键性代码

public class TakePhotosActivity extends CheckPermissionsActivity implements View.OnClickListener {
    private ImageView photoTv1;
 private final static int TAKEPHOTOCODE = 110;
    private String sdState;
    private ImageView openPhotoIv;
    // /storage/emulated/0/pic
    public final static String SAVED_IMAGE_PATH1 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pic";//+"/pic";
    // /storage/emulated/0/Pictures
    public final static String SAVED_IMAGE_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath();//.getAbsolutePath()+"/pic";//+"/pic";
    String photoPath;
    Bitmap bp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_photos);
        //获取SD卡安装状态
        sdState = Environment.getExternalStorageState();
        init();
    }

    private void init() {
        findViewById();
        setListener();
    }

    private void findViewById() {
        photoTv1 = (ImageView) findViewById(R.id.take_photos_1);
    }

    private void setListener() {
        photoTv1.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.take_photos_1:
                if (sdState.equals(Environment.MEDIA_MOUNTED)) {
                    //设置图片保存路径
                    photoPath = SAVED_IMAGE_PATH + "/" + System.currentTimeMillis() + ".png";

                    File imageDir = new File(photoPath);
                    if (!imageDir.exists()) {

                        //根据一个 文件地址生成一个新的文件用来存照片
                        try {
                            imageDir.createNewFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        takePhotos();
                    }

                } else {
                    Toast.makeText(TakePhotosActivity.this, "SD卡未插入", Toast.LENGTH_SHORT).show();
                }
                break;

        }

    }

    private void takePhotos() {
//考虑到安全机制的问题,Android的SDK25以后对相机调用有了新的限定,在这里要做一下处理
 int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        //根据路径实例化图片文件
        File photoFile = new File(photoPath);
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (currentapiVersion < 24) {

            //设置拍照后图片保存到文件中
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            //启动拍照activity并获取返回数据
            startActivityForResult(intent, TAKEPHOTOCODE);
        } else {
            ContentValues contentValues = new ContentValues(1);
            contentValues.put(MediaStore.Images.Media.DATA, photoFile.getAbsolutePath());
            Uri uri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            startActivityForResult(intent, TAKEPHOTOCODE);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TAKEPHOTOCODE && resultCode == Activity.RESULT_OK) {
            File photoFile = new File(photoPath);
            if (photoFile.exists()) {
                //通过图片地址将图片加载到bitmap里面
                Bitmap bm = BitmapFactory.decodeFile(photoFile.getAbsolutePath());

//添加日期水印
 bp = ImageUtils.addTimeFlag(bm);
                //将拍摄的照片显示到界面上
                photoTv1.setImageBitmap(bp);
            } else {
                Toast.makeText(TakePhotosActivity.this, "没有图片数据", Toast.LENGTH_SHORT).show();
            }

        }
    }


}
下面放上添加水印的源码,可以抽出来直接用

public class ImageUtils {
    /**
     * 添加时间水印
     * @param
     */
    public static Bitmap addTimeFlag(Bitmap src){
        // 获取原始图片与水印图片的宽与高
        int w = src.getWidth();
        int h = src.getHeight();
        Bitmap newBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas mCanvas = new Canvas(newBitmap);
        // 往位图中开始画入src原始图片
        mCanvas.drawBitmap(src, 0, 0, null);
        //添加文字
        Paint textPaint = new Paint();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String time = sdf.format(new Date(System.currentTimeMillis()));
        textPaint.setColor(Color.RED) ;
        textPaint.setTextSize(100);
        String familyName = "宋体";
//        Typeface typeface = Typeface.create(familyName,
//                Typeface.BOLD_ITALIC);
//        textPaint.setTypeface(typeface);
//        textPaint.setTextAlign(Align.CENTER);

        mCanvas.drawText(time, (float)(w*1)/7, (float)(h*14)/15, textPaint);
        mCanvas.save(Canvas.ALL_SAVE_FLAG);
        mCanvas.restore();
        return newBitmap ;
    }
}
知道你们想看效果,正所谓没图说个xx啊!来张效果图


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值